I am trying to make a PL/SQL function that when given the customer number looks to see if the order was sent to the customer address. If the customer's address matches the order address then the function needs to return True. This is what I came up with but I can't get it to work. Any help would be appreciated.
CREATE OR REPLACE Function CorrectAddress
(aCustNo IN Customer.CustNo%TYPE) RETURN VARCHAR IS
aCustStreet Customer.CustStreet%TYPE;
aCustCity Customer.CustCity%TYPE;
aCustState Customer.CustState%TYPE;
aOrdStreet OrderTbl.OrdStreet%TYPE;
aOrdCity OrderTbl.OrdCity%TYPE;
aOrdState OrderTbl.OrdState%TYPE;
RightAdd VARCHAR;
BEGIN
SELECT Customer.CustStreet, Customer.CustCity, Customer.CustState OrderTbl.OrdStreet, OrderTbl.OrdCity, OrderTbl.OrdState
INTO aCustStreet, aCustCity, aCustState, aOrdStreet, aOrdCity, aOrdState
FROM Customer, OrdertTbl
WHERE Customer.CustNo = OrderTbl.CustNo;
IF aCustStreet = aOrdStreet AND aCustCity = aOrdCity AND aCustState = aOrdState THEN RightAdd := True;
ELSE RightAdd := False;
END IF;
END;
Try this one, why did you want to return 'varchar', is it your custom type? if you want to return true/false you have to come with 'boolean', also you need to check whether you have rows in the table, for that you need to put exception handler
`CREATE OR REPLACE Function CorrectAddress
(aCustNo IN Customer.CustNo%TYPE) RETURN boolean IS
aCustStreet Customer.CustStreet%TYPE;
aCustCity Customer.CustCity%TYPE;
aCustState Customer.CustState%TYPE;
aOrdStreet OrderTbl.OrdStreet%TYPE;
aOrdCity OrderTbl.OrdCity%TYPE;
aOrdState OrderTbl.OrdState%TYPE;
`BEGIN
SELECT
Customer.CustStreet,
Customer.CustCity,
Customer.CustState,
OrderTbl.OrdStreet,
OrderTbl.OrdCity,
OrderTbl.OrdState
INTO
aCustStreet,
aCustCity,
aCustState,
aOrdStreet,
aOrdCity,
aOrdState
FROM
Customer,
OrdertTbl
WHERE Customer.CustNo = OrderTbl.CustNo;`
`IF aCustStreet = aOrdStreet AND aCustCity = aOrdCity AND aCustState = aOrdState THEN
return true;
ELSE
return false;
END IF;`
`Exception
when no_data_found then
return false;`
`END;`
why not do something in these lines, much cleaner to read and why use all these fields when they are not needed (haven't tested the plsql block, but for the general idea check below);
declare
V_COUNTER number := 0;
V_RESULT boolean;
begin
select
count('x')
into
V_COUNTER
from
Order o
inner join Customer c on c.Street = o.Street and
c.City = o.City and
c.State = o.State
where
o.Orderid = 100100;
if V_COUNTER = 0 then
V_RESULT := False;
else
V_RESULT := True;
end if;
end;
Related
I have created this function and it works:
create or replace function log_in(
p_ssnr in customer.ssnr%type,
p_password in customer.password%type)
return number
as
v_number number(1);
begin
if
(p_ssnr is not null and p_password is not null) then
v_number:= 1;
else
v_number:= 0;
end if;
return v_number;
end;
If I then type: select log_in('social security number','the password') from dual; then I get a "1"
so it works. But you could basically type whatever you want and it will work so it is not a clean code. Since you can't include subquery in the if statement, how can you create the function so you only return 1 when you actually type a social security number (ssnr) and a password that matches the actual customer table? and otherwise you return 0?
NOt sure if you can have multiple rows for same customer. If yes, then use this:
create or replace function log_in(
p_ssnr in customer.ssnr%type,
p_password in customer.password%type)
return number
as
v_number number(1);
begin
select case when count(*) > 0 then 1 else 0 end
into v_number
from customer
where ssnr = p_ssnr and password = p_password;
return v_number;
end;
If not then this should be fine:
create or replace function log_in(
p_ssnr in customer.ssnr%type,
p_password in customer.password%type)
return number
as
v_number number(1);
begin
count(*)
into v_number
from customer
where ssnr = p_ssnr and password = p_password;
return v_number;
end;
Unfortunately my validation doesn't work when i click a submit button. When I do click the submit button 'what' appears as error which is b = null below. How would you validate a registration page after the person presses the submit button. Or how would you do validation after submit button?
DECLARE
error_message varchar2(4000);
b varchar2(500);
FUNCTION validate_field RETURN VARCHAR2
AS
BEGIN
b := :P101_REG_FIRST_NAME;
IF (REGEXP_LIKE(b, '[A-Za-z]') AND :P101_NEW <> NULL AND NOT(REGEXP_LIKE(b, '[:space:]'))) THEN
RETURN 'works' || b;
ELSIF b IS NULL THEN
RETURN b || 'what';
ELSIF REGEXP_COUNT(b, '[A-Za-z]') = 1 THEN
RETURN 'Name cannot be single letter';
ELSE RETURN 'HUH' || ' ' || b;
END IF;
END;
BEGIN
error_message := '';
error_message := validate_field;
IF error_message IS NULL THEN
RETURN NULL;
ELSE
RETURN error_message;
END IF;
COMMIT;
END;
I solved it. I'll post the answer in the morning, it's late and I've stayed up too long solving this issue. I feel good though. Thank you for reading all of this.
I write this function in oracle PL/SQL to return counter of employee in the university based on their sex and collage nationality,sex , grade and qualification ETC.
FUNCTION GET_EMP_COUNT_GENERIC (
P_ORGANIZATION_ID VARCHAR2,
P_GRADE VARCHAR2,
P_SEX VARCHAR2,
P_NAT_TYPE VARCHAR2,
P_DATE DATE,
P_EMP_TYPE VARCHAR2,
P_QUALIFIC_CAT VARCHAR2 )
RETURN NUMBER IS
V_COUNT NUMBER;
BEGIN
SELECT COUNT (EMP.PERSON_ID) INTO V_COUNT
FROM PER_ALL_ASSIGNMENTS_F ASS,
PER_ALL_PEOPLE_F EMP,
HR_ALL_ORGANIZATION_UNITS ORG,
PAY_PEOPLE_GROUPS PPG,
PER_GRADES GRD
WHERE ASS.PERSON_ID = EMP.PERSON_ID
AND ASS.ORGANIZATION_ID = ORG.ORGANIZATION_ID
AND ASS.PEOPLE_GROUP_ID = PPG.PEOPLE_GROUP_ID
AND ASS.GRADE_ID = GRD.GRADE_ID
AND EMP.PERSON_TYPE_ID = 1145
AND (ASS.ORGANIZATION_ID = P_ORGANIZATION_ID OR P_ORGANIZATION_ID IS NULL)
AND (GRD.NAME = P_GRADE OR P_GRADE IS NULL)
AND (EMP.SEX = P_SEX OR P_SEX IS NULL)
AND (PPG.SEGMENT2 = P_NAT_TYPE OR P_NAT_TYPE IS NULL)
AND (PPG.SEGMENT1 =P_EMP_TYPE OR P_EMP_TYPE IS NULL)
AND (XXPNU_HCM_PKG.GET_QUALIFICATION_NAME(EMP.PERSON_ID,EMP.BUSINESS_GROUP_ID)
= P_QUALIFIC_CAT OR P_QUALIFIC_CAT IS NULL)
AND P_DATE BETWEEN ASS.EFFECTIVE_START_DATE
AND ASS.EFFECTIVE_END_DATE
AND P_DATE BETWEEN EMP.EFFECTIVE_START_DATE
AND EMP.EFFECTIVE_END_DATE;
RETURN V_COUNT;
END GET_EMP_COUNT_GENERIC;
But when I call it in query, its return null or zero value??
i dont know what is my mistake
SELECT
XXPNU_HCM_PKG.GET_EMP_COUNT_GENERIC (null,null,'M',null,:P_DATE,'FACULTY',null) as FACULTY_M,
XXPNU_HCM_PKG.GET_EMP_COUNT_GENERIC (null,null,'F',null,:P_DATE,'FACULTY',null) as FACULTY_F
--------------------------------TABLES------------------------------------------
FROM PER_ALL_ASSIGNMENTS_F ASS,
PER_ALL_PEOPLE_F EMP,
HR_ALL_ORGANIZATION_UNITS ORG,
PAY_PEOPLE_GROUPS PPG,
PER_GRADES GRD
--------------------------------- CONDITIONS -----------------------------------
WHERE
ASS.PERSON_ID = EMP.PERSON_ID
AND ASS.ORGANIZATION_ID = ORG.ORGANIZATION_ID
AND ASS.PEOPLE_GROUP_ID = PPG.PEOPLE_GROUP_ID
AND ASS.GRADE_ID = GRD.GRADE_ID
AND EMP.PERSON_TYPE_ID = 1145
--------------------------------THIS YEAR DATE ---------------------------------
AND :P_DATE BETWEEN ASS.EFFECTIVE_START_DATE
AND ASS.EFFECTIVE_END_DATE
AND :P_DATE BETWEEN EMP.EFFECTIVE_START_DATE
AND EMP.EFFECTIVE_END_DATE ;
Your function will return 0 when it finds no rows that match your predicates in the function.
And because you use the function in the select-section of a select-statement it will return NULL when a exception occurs within the function.
Try using an exceptio handler returning -1. Then you know an exception occured.
remenber, an exception is not handled when a function is called within a select statement (in all DML I would say, but I don't know that for sure)
I have below procedure in which i want to return the output of variable value brand_name.BRAND_NAME. I am getting the correct output. But i want to return it in proper format. For example right now i am getting the output as
BRAND_NAMES:FNC
BRAND_NAMES:LIDL
But i want to return the output as:
BRAND_NAME: FNC,LIDL
Here is my stored procedure:
FUNCTION BUILD_ALERT_EMAIL_BODY
(
IN_ALERT_LOGS_TIMESTAMP IN TIMESTAMP
, IN_ALERT_LOGS_LOG_DESC IN VARCHAR2
, IN_KPI_LOG_ID IN NUMBER
) RETURN VARCHAR2 AS
BODY VARCHAR2(4000) := '';
V_KPI_DEF_ID NUMBER := '';
V_BRAND_NAME VARCHAR2(100) := '';
V_KPI_TYPE_ID NUMBER := '';
CURSOR brand_names_cur
IS
Select BR.NAME AS BRAND_NAME INTO V_BRAND_NAME FROM RATOR_MONITORING_CONFIGURATION.KPI_DEFINITION KD JOIN RATOR_MONITORING_CONFIGURATION.KPI_DEFINITION_BRAND KDB ON KD.KPI_DEF_ID = KDB.KPI_DEF_ID JOIN
RATOR_MONITORING_CONFIGURATION.BRAND BR ON KDB.BRAND_ID = BR.BRAND_ID WHERE KD.KPI_DEF_ID = V_KPI_DEF_ID;
BEGIN
Select KPI_DEF_ID INTO V_KPI_DEF_ID FROM KPI_LOGS WHERE KPI_LOG_ID = IN_KPI_LOG_ID;
Select KT.KPI_TYPE_ID INTO V_KPI_TYPE_ID FROM RATOR_MONITORING_CONFIGURATION.KPI_DEFINITION KD JOIN RATOR_MONITORING_CONFIGURATION.KPI_TYPE KT ON KD.KPI_TYPE = KT.KPI_TYPE_ID WHERE KD.KPI_DEF_ID = V_KPI_DEF_ID;
FOR brand_name IN brand_names_cur
LOOP
BODY := BODY || 'BRAND_NAME:' || brand_name.BRAND_NAME || Chr(10) || Chr(13);
END LOOP;
BODY := BODY || 'ALERT_DESCRIPTION:' || to_char(IN_ALERT_LOGS_LOG_DESC);
RETURN BODY;
END BUILD_ALERT_EMAIL_BODY;
Add V_FIRST_RECORD variable
V_FIRST_RECORD Boolean := true;
and use it in your loop like this
if v_first_record then
body := 'BRAND_NAME: '||brane_name.BRAND_NAME;
else
body := body ||','||brane_name.BRAND_NAME;
v_first_record := false;
end if;
Using TADOCommand to update a record.
using TADOCommand to insert a new record.
Name of table is Board
Using MS Access database
I get an error
Syntax error in UPDATE/INSERT INTO statement
I can connect and retrieve data just fine. Just never added or updated data before.
My database columns looks like this
ID (auto number)
SN (text)
CardType (text)
Desc (memo)
dbDate (date)
Tech (text)
Code looks like this:
procedure TForm2.BSaveClick(Sender: TObject);
const
sqlStringNew = 'INSERT INTO Board (SN,CardType,Desc,dbDate,Tech) VALUES (:aSN,:aCardType,:aDesc,:aDate,:aTech);';
sqlStringUpdate = 'UPDATE Board SET SN=:aSN, CardType=:aCardType, Desc=:aDesc, dbDate=:aDate, Tech=:aTech WHERE ID = :aID;';
var
ADOCommand : TAdoCommand;
begin
ADOCommand := TADOCommand.Create(nil);
// updating a board
if NewBoard = false then
begin
try
ADOCommand.Connection := adoConnection1;
ADOCommand.Parameters.Clear;
ADOCommand.Commandtext := sqlStringUpdate;
ADOCommand.ParamCheck := false;
ADOCommand.Parameters.ParamByName('aSN').Value := ESerialNumber.Text;
ADOCommand.Parameters.ParamByName('aCardType').Value := ECardType.Text;
ADOCommand.Parameters.ParamByName('aDesc').Value := MDescription.Text;
ADOCommand.Parameters.ParamByName('aDate').Value := strtodate(EDate.Text);
ADOCommand.Parameters.ParamByName('aTech').Value := ETech.Text;
ADOCommand.Parameters.ParamByName('aID').Value := UpdateID;
ADOCommand.Execute;
finally
ADOCommand.Free;
end;
Showmessage('Update Complete');
end;
//if a new board
if NewBoard = True then
Begin
try
ADOCommand.Connection := adoConnection1;
ADOCommand.Parameters.Clear;
ADOCommand.Commandtext := sqlStringNew;
ADOCommand.ParamCheck := false;
ADOCommand.Parameters.ParamByName('aSN').Value := ESerialNumber.Text;
ADOCommand.Parameters.ParamByName('aCardType').Value := ECardType.Text;
ADOCommand.Parameters.ParamByName('aDesc').Value := MDescription.Text;
ADOCommand.Parameters.ParamByName('aDate').Value := strtodate(EDate.Text);
ADOCommand.Parameters.ParamByName('aTech').Value := ETech.Text;
ADOCommand.Execute;
finally
ADOCommand.Free;
end;
NewBoard := false;
BSave.Enabled := false;
NoEdit;
Showmessage('New Record Added');
End;
end;
It is advisable not to use SQL keywords for table and field names. DATE is a function in many SQL dialects. If you choose to use a reserved word/function name for a table/field name, you have to escape it in SQL statement: [Date] for SQL Server and MS Access, "Date" - for Oracle.