How does PLSQL function return text validation work? - sql

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.

Related

function in plsql

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;

Cursor for loop to return output in proper format in oracle stored procedure

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;

Oracle 11g - Find Records in a CLOB with Carriage Return Line Feed

I am on Oracle 11g. I am trying to do a Find and Replace functionality on a CLOB field (using REPLACE).
Now the data in my CLOB has CRLFs in them, the replace works just fine until I want to find a string that contains CRLFs. Perhaps this would be best explained by example:
So say the text in my field is:
----------------------------------
Hi there this is some text
that has CRLFS in it.
Some other text that
is there also.
Have a nice day
Now what I want to do is replace all occurrences of this INCLUDING the CRLFs:
Search Text
--------------------------------------------------------------------------------
Some other text that
is there also.
With this text INCLUING the CRLFs:
Replace Text
------------------------------------
Some other text that
has some new text that is there also.
So That could come out to be:
----------------------------------
Hi there this is some text
that has CRLFS in it.
Some other text that
has some new text that is there also.
Have a nice day
Now I am doing this in a stored procedure and the Search Text and Replace Text come in as variables, but When I try and say where like % || ReplaceText || '%' it returns 0 rows.
Does anyone have an idea how to do this?
Here is my stored procedure (iOldResponsibilities is the Search Text, iNewResponsibilities is the replace text:
PROCEDURE FindReplaceResponsibilities (
iOldResponsibilities IN JP_JOB_FAMILIES.RESPONSIBILITIES%TYPE,
iNewResponsibilities IN JP_JOB_FAMILIES.RESPONSIBILITIES%TYPE,
oNumRowsUpdated OUT INTEGER
)
IS
BEGIN
oNumRowsUpdated := 0;
SAVEPOINT sp_jf_findrepresp;
-- If there is no old text to search for then,
-- append the new text to the end of every row.
-- Else replace all occurrences of the old text with the new text
IF iOldResponsibilities IS NULL THEN
UPDATE JP_JOB_FAMILIES
SET RESPONSIBILITIES = RESPONSIBILITIES || iNewResponsibilities;
oNumRowsUpdated := SQL%ROWCOUNT;
ELSE
UPDATE JP_JOB_FAMILIES
SET RESPONSIBILITIES = REPLACE(RESPONSIBILITIES, iOldResponsibilities, iNewResponsibilities)
WHERE RESPONSIBILITIES like '%' || iOldResponsibilities || '%';
-- I have also tried this:
--WHERE dbms_lob.instr(RESPONSIBILITIES, TO_CLOB(iOldResponsibilities)) > 0; -- This is a LIKE for CLOBS
oNumRowsUpdated := SQL%ROWCOUNT;
END IF;
RETURN;
EXCEPTION
WHEN OTHERS THEN
BEGIN
oNumRowsUpdated := -1;
ROLLBACK TO sp_jf_findrepresp;
dbms_output.put_line('error: ' || sqlerrm);
RETURN;
END;
END FindReplaceResponsibilities;
The Text is coming from an asp.net application (c#) as String values:
public int FindReplaceJobFamilyResponsibilities(String oldResponsibilities, String newResponsibilities, IDbTransaction transaction = null)
{
using (IDbCommand cmd = this._dataHelper.GetStoredProcedure(_connectionString,
"JP_JOBFAM_PKG.FindReplaceResponsibilities", true))
{
_dataHelper.SetParameterValue(cmd, "iOldResponsibilities", oldResponsibilities);
_dataHelper.SetParameterValue(cmd, "iNewResponsibilities", newResponsibilities);
DataHelperBase.VerifyParameters(cmd.Parameters, false);
base.SetExecuteConnection(cmd, transaction);
_dataHelper.ExecuteNonQuery(cmd);
return Convert.ToInt32(_dataHelper.GetParameterValue(cmd, "oNumRowsUpdated"));
}
}
Turns out to be a case of bad data. The data in my Test DB was corrupted and only had LFs instead of CRLFs.
GIGO :-)
Thanks for all your help
Oh and by the way In my code example I went with the INSTR function instead of the like function. If the user entered a % in the text to search through that might have messed up the like statement. (Can't filter those out because % might be a valid character in my data)
Here is the Final Code:
PROCEDURE FindReplaceResponsibilities (
iOldResponsibilities IN JP_JOB_FAMILIES.RESPONSIBILITIES%TYPE,
iNewResponsibilities IN JP_JOB_FAMILIES.RESPONSIBILITIES%TYPE,
oNumRowsUpdated OUT INTEGER
)
IS
BEGIN
oNumRowsUpdated := 0;
SAVEPOINT sp_jf_findrepresp;
-- If there is no old text to search for then,
-- append the new text to the end of every row.
-- Else replace all occurrences of the old text with the new text
IF iOldResponsibilities IS NULL THEN
UPDATE JP_JOB_FAMILIES
SET RESPONSIBILITIES = RESPONSIBILITIES || iNewResponsibilities;
oNumRowsUpdated := SQL%ROWCOUNT;
ELSE
UPDATE JP_JOB_FAMILIES
SET RESPONSIBILITIES = REPLACE(RESPONSIBILITIES, iOldResponsibilities, iNewResponsibilities)
WHERE dbms_lob.instr(RESPONSIBILITIES, iOldResponsibilities) > 0;
oNumRowsUpdated := SQL%ROWCOUNT;
END IF;
RETURN;
EXCEPTION
WHEN OTHERS THEN
BEGIN
oNumRowsUpdated := -1;
ROLLBACK TO sp_jf_findrepresp;
dbms_output.put_line('error: ' || sqlerrm);
RETURN;
END;
END FindReplaceResponsibilities;
The code from my application was fine:
public int FindReplaceJobFamilyResponsibilities(String oldResponsibilities, String newResponsibilities, IDbTransaction transaction = null)
{
using (IDbCommand cmd = this._dataHelper.GetStoredProcedure(_connectionString,
"JP_JOBFAM_PKG.FindReplaceResponsibilities", true))
{
_dataHelper.SetParameterValue(cmd, "iOldResponsibilities", oldResponsibilities);
_dataHelper.SetParameterValue(cmd, "iNewResponsibilities", newResponsibilities);
DataHelperBase.VerifyParameters(cmd.Parameters, false);
base.SetExecuteConnection(cmd, transaction);
_dataHelper.ExecuteNonQuery(cmd);
return Convert.ToInt32(_dataHelper.GetParameterValue(cmd, "oNumRowsUpdated"));
}
}

PL/SQL Function for Correct Shipping Address

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;

Updating a record in database

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.