I am trying to send a return message to front end. If the parameter which is passed, if it is not in format like
'A-1213-465-798-01'
It should reply back 1. But I am missing out the validation. please help.
'A-1213-465-798-01'
IF #OptParam3 not like '[_-_-_-_-_]'
Begin
Set #Return_Message = '1' -- Validation 'Invalid code
Print 'Error: Invalid Code'
Return
End
Assuming this is a stored procedure you probably want something along the lines of this
IF OBJECT_ID('sp_demo') > 0 DROP PROC sp_demo
go
CREATE PROC sp_demo (#OptParam1 varchar(50),#OptParam2 varchar(50),#OptParam3 varchar(50))
AS
IF #OptParam3 not like '_-____-___-___-__'
Begin
Print 'Error: Invalid Code'
Return 1
End
/*
If we got here then the parameter is validated
*/
PRINT '#OptParam3 is valid:'
PRINT #OptParam3
Return 0
You can check this by doing the following
/* Driver to test the stored procedure */
DECLARE #return_Code int
EXEC #return_Code = sp_demo 'parameterA','parameterB','A-1213-465-798-01';
PRINT #return_Code
But really you should probably be raising an error in your code if your input parameters are invalid. This will come through as a trapable error in your front end
IF OBJECT_ID('sp_demo') > 0 DROP PROC sp_demo
go
CREATE PROC sp_demo (#OptParam1 varchar(50),#OptParam2 varchar(50),#OptParam3 varchar(50))
AS
IF #OptParam3 not like '_-____-___-___-__'
Begin
RAISERROR (N'Error: Invalid Code "%s"',16,1 ,#OptParam3)
return ##ERROR
End
/*
If we got here then the parameter is validated
*/
PRINT '#OptParam3 is valid:'
PRINT #OptParam3
Return 0
Related
I am trying to execute a THROW statement like so (value and 12345 being some random values):
use testdb;
go
begin try
if('value' in (select distinct shelf from itemloc))
update itemloc
set shelf = 'value'
where item = '12345';
end try
begin catch
;Throw 160073, 'Failed to update shelf value', 1;
end catch;
Using this reference
I looked at this question and I have the ; before my THROW. I'm also checking the syntax against the reference and fail to see why executing this returns
Msg 102, Level 15, State 1, Line 11
Incorrect syntax near 'Throw'.
You're inside a CATCH, you can't choose your error here, you would just use THROW;. Also, you don't need to start your statement with a semicolon, you already put one at the end of your last statement. It's a terminator (it goes at the end of the line), not at the beginning and end.
If you want to use a custom error, use RAISERROR. For example:
USE TESTDB;
GO
BEGIN TRY
IF('value' IN (SELECT DISTINCT shelf FROM itemloc))
UPDATE itemloc
SET shelf = 'value'
WHERE item = '12345';
END TRY
BEGIN CATCH
DECLARE #ERROR VARCHAR(MAX);
SET #ERROR = 'Failed to update shelf value';
RAISERROR(#ERROR, 11, 160073);
END CATCH
Hello there I have a Function and is introduction a variable which will bring a letter or a number, if the variable is a letter it need to cause an error and return a 0, or if is a number then return 1.
SO in T-SQL I have a Procedure that eventually will call this function to check is is a number:
IF dbo.VALIDNUMBER(#sTxpX) != 0 AND #sTxpX IS NOT NULL
The variable #sTxpX is holding a value which is 'T' so I know it needs to return 0 from the function because is invalid to be a numeric, but Im not getting the proper function to build it, I will appreciate some help here.
CREATE FUNCTION DBO.VALIDNUMBER (#sTextStr VARCHAR(4000)) RETURNS BIT AS
BEGIN
DECLARE #bValidNumberStr BIT = 1; DECLARE #nTest BIGINT;
SET #nTest = CAST(#sTextStr AS numeric(38, 10)) + 1;
RETURN #bValidNumberStr;
EXCEPTION
WHEN OTHERS THEN
SET #bValidNumberStr = 0;
RETURN #bValidNumberStr;
END;
Try this function:
CREATE function [dbo].[VALIDNUMBER]
(#strText VARCHAR(4000))
RETURNS BIT
AS
BEGIN
DECLARE #Return as bit
IF TRY_CAST(#strText AS NUMERIC(38,10)) IS NOT NULL BEGIN
SET #Return = 1
END ELSE BEGIN
SET #Return = 0
END
RETURN #Return
END
Why can't you use the built-in SQL function? It's faster, and no need for you to drive yourself crazy to come up with a solution.
In your procedure do the following:
DECLARE #isNumber bit;
IF (ISNUMERIC(#sTextStr) = 1)
BEGIN
SET #isNumber = 1
END
ELSE
BEGIN
SET #isNumber = 0
RAISERROR(15600, 16, 20, 'That was not a number')
END
You can pass the #isNumber variable back to the user at a later point in time.
I am new to PLSQL. I am trying to create a procedure which iterates through an array.
My requirement is if one of the value is not found in table, it should add into FAILARRAY, otherwise it should add into PASSARRAY.
I was getting no data found exception even if it is handled, it goes out of the loop and next value in the loop is not getting iterated again.
Is there any way we can use if exists command here. Please help.
CREATE OR REPLACE PROCEDURE SCHEMA.PR_VALIDATE
(
FILEARRAY IN STRARRAY,
PASSARRAY OUT STRARRAY,
FAILARRAY OUT STRARRAY,
)
IS
--DECLARE
fileName VARCHAR2 (50);
fileId NUMBER;
BEGIN
for i in 1 .. FILEARRAY.count
loop
fileName := FILEARRAY(i);
DBMS_OUTPUT.put_line (FILEARRAY (i));
SELECT FILEID into fileId FROM TABLE_NAME WHERE FILENAME=fileName;
end loop
END;
I suspect you haven't realised that you can have a PL/SQL BEGIN ... END block, including an exception handler, within a loop. In fact, anywhere you can have PL/SQL statements you can have a block.
You mention an exception handler, although your code doesn't contain one. As you say your code goes 'out of the loop', I can only assume it's, well, outside of the for loop. But you can easily add a block, with an exception handler, inside the for loop, for example:
BEGIN
for i in 1 .. FILEARRAY.count
loop
fileName := FILEARRAY(i);
DBMS_OUTPUT.put_line (FILEARRAY (i));
-- Inner block starts at the line below:
BEGIN
SELECT FILEID into fileId FROM TABLE_NAME WHERE FILENAME=fileName;
-- TODO add to PASSARRAY
EXCEPTION
WHEN NO_DATA_FOUND THEN
-- TODO add to FAILARRAY
END;
end loop
END;
This way, if there are 8 values in FILEARRAY and no data is found in the table for the third value, the NO_DATA_FOUND exception gets caught without exiting the loop and the loop then progresses to the fourth value in FILEARRAY.
You are handling the exception but you need to avoid the exception. Try:
SELECT NVL(FILEID, "<Put Something here or leave it empty") FROM TABLE_NAME WHERE FILENAME=fileName;
That way if it finds a null value in the select it will just pull "" instead. Then you can check to see if your SELECT returns "" and if so populate your FAILARRAY, otherwise populate PASSARRAY.
CREATE OR REPLACE PROCEDURE SCHEMA.PR_VALIDATE(
FILEARRAY IN STRARRAY,
PASSARRAY OUT STRARRAY,
FAILARRAY OUT STRARRAY )
IS
fileName VARCHAR2 (50);
l_n_count NUMBER;
l_n_file_id NUMBER;
BEGIN
FOR i IN 1 .. FILEARRAY.count
LOOP
fileName := FILEARRAY(i);
DBMS_OUTPUT.put_line (FILEARRAY(i));
SELECT COUNT(FILEID) INTO l_n_count FROM TABLE_NAME WHERE FILENAME=fileName;
IF l_n_count =0 THEN
failarray(i):='No Value Found';
elsif l_n_count=1 THEN
SELECT FILEID INTO l_n_file_id FROM TABLE_NAME WHERE FILENAME=fileName;
Passarray(i):=l_n_file_id;
END IF;
END LOOP;
END;
/
CREATE PROCEDURE [dbo].[spTest]
#Pozitii varchar(max),
#NrZile int
AS
set #Pozitii = SUBSTRING(#Pozitii,0,LEn(#Pozitii))
CREATE TABLE #Pozitii (part varchar(20) null)
INSERT INTO #Pozitii(part)
SELECT part
FROM dbo.SDF_SplitString(#Pozitii,',')
if exists (SELECT * FROM #Pozitii)
RAISERROR('asdf',16,-1)
else RAISERROR('else',16,-1)
So runing this SP in SQL like this
exec [spTest] '11,12,13,',1
Returns:
(3 row(s) affected)
Msg 50000, Level 16, State 1, Procedure spTest, Line 27
asdf
Now if I run my procedure in delphi ( using an ADO object)
procedure TframePlanificatorPozitieComanda.Button5Click(Sender: TObject);
begin
try
with dm.spTest do
begin
Close;
Parameters.ParambyName('#Pozitii').Value := '11,12,13,';
Parameters.ParambyName('#NrZile').Value := 1;
ExecProc;
end;
except
on E: Exception do
begin
ShowMessage(E.Message);
end;
end;
end;
This code is not raising any errors?Any ideas why?
Have you tried adding:
SET NOCOUNT ON;
to your stored procedure? I think the exception is in a second resultset and is getting hidden by the first select result count.
The error is raising in sql-server.. but in delphi is not .. because there the procedure is already executed..
But in Delphi you can check if the procedure is run successfully or not regards what the result of the procedure (some of procedures have no output parameters).
In delphi please check your adostoredprocedure.parameters[0] like:
showmessage(vartostr(self.ADOStoredProc1.Parameters[0].Value))
.
if the result <> 0 that means error.
Using Sql Server 2014, I don't get the behaviour you describe.
I have a stored proc on the server defined as
CREATE PROCEDURE spRaiseError(#AnError int)
AS
BEGIN
declare #Msg Char(20)
if #AnError > 0
begin
Select #Msg = 'MyError ' + convert(Char(8), #AnError)
RaisError(#Msg, 16, -1)
end
else
select 1
END
I have a minimalist D7 Ado project with a TAdoConnection, TAdoQuery, TDataSource and TDBGrid connected up as you'd expect, a TEdit and a TButton.
Using this code
procedure TForm1.Button1Click(Sender: TObject);
var
S : String;
ErrorCount : Integer;
begin
S := 'exec spRaiseError ' + Edit1.Text;
AdoQuery1.SQL.Text := S;
try
AdoQuery1.Open;
except
end;
ErrorCount := AdoConnection1.Errors.Count;
Caption := IntToStr(ErrorCount);
end;
, if the number in Edit1 is > 0 I get only the error number on the form's caption, whereas if it contains 0 I see the value 1 in the DBGrid.
Btw, with "Stop on language exceptions" checked in the D7 debugger settings, without the try/except around AdoQuery1.Open, the debugger sees and catches the exception from the server.
Anyway, the take-home message from this answer is that you can use the TAdoConnection's Errors collection to detect whether there was an error and, if there was, you can get more information from it. See the Delphi OLH amd MS Ado documentation for more info about the Errors collection of TAdoConnection and other Ado-based Delphi classes.
I would like to take the code below and create a common function to pass in one or more expressions and to return back an error of my choosing.
Example Code:
IF #Variable1 IS NULL AND #Variable IS NULL or #Variable3 is not null
BEGIN
-- EITHER DATASET NAME OR ID MUST BE SUPPLIED.
SET #_msg = 'There was an error'
SET #_returnValue = -1
GOTO ERROR_HANDLER
END
ERROR_HANDLER:
-- CREATE THE CLOSING MESSAGE.
IF #_returnValue <> 0
RAISERROR(#_msg, 18, 2) WITH SETERROR
RETURN #_returnValue
From the above, it would be nice to say something like this below where I could reuse the proc/function and make the code less clutered.
exec ValidateMultipleConditions #Variable1 + 'IS NULL AND ' + #Variable + 'IS NULL or ' + #Variable3 + ' is not null'
Anyway, I think with dynamic SQL being passed in this way I could do something where an complete expression could be sent evaluated, validated and then the code continues or stops with an error.
I wanted to see if the community had better ways of doing this or if I'm on the right path.
Thanks.
I'm not quite sure if I get your question right. But you can easily create an procedure (if it's needed).
CREATE PROCEDURE dbo.errorout #message nvarchar(100), #sev int, #state int
AS
BEGIN
RAISERROR(#message,#sev,#state) WITH NOWAIT
END
But I won't use this at all. I would call RAISERROR() in the place where it occurs, as it will give you more accurate line numbers and procedures in the errorlog.