How to write conditions in a SQL stored procedure? - tsql

I've got this stored procedure:
IF OBJECT_ID('[dbo].[GetSessionInfo]') IS NOT NULL
DROP PROCEDURE [dbo].[GetSessionInfo]
GO
CREATE PROCEDURE [dbo].[GetSessionInfo](
#SessionID int)
WITH ENCRYPTION
AS
BEGIN
SET NOCOUNT ON;
SELECT [cfgGroup].[Name] as GroupName,[cfgSession].[Name],[cfgSession].[GroupId],[cfgSession].[IsDisabled],
[cfgSession].[IsTestSession],[cfgSession].[NextExecutionTime],[cfgSession].[SType],[cfgSession].[DaysToKeep],
[cfgSchedule].[ID],[cfgSchedule].[SessionId],[cfgSchedule].[MinuteFreq],[cfgSchedule].[HourFreq],
[cfgSchedule].[Daily],[cfgSchedule].[WeekFreq],[cfgSchedule].[StartDate],[cfgSchedule].[EndDate],
[cfgSchedule].[NoOrderDays],[cfgSchedule].[OrderDays],[cfgData].[ID],[cfgData].[SessionId],[cfgData].[StationExclude],
[cfgData].[StationFilter],[cfgData].[ConsoleExclude],[cfgData].[ConsoleFilter],[cfgData].[MedClassesExclude],[cfgData].[MedClassesFilter],[cfgData].[PickAreasExclude],
[cfgData].[PickAreasFilter], [cfgData].[DeviceType]
FROM [cfgGroup],[cfgSession],[cfgSchedule],[cfgData]
WHERE [cfgGroup].[ID] = [cfgSession].[GroupId]
AND
[cfgSession].[ID] = #SessionID
AND
[cfgSchedule].[SessionId] = [cfgSession].[ID]
AND
[cfgData].[SessionId] = [cfgSchedule].[SessionId]
END
GO
I need to change what data the stored procedure returns based on what is in [cfgSession].[SType]
[cfgSession].[SType] can only be Send or Receive
If [cfgSession].[SType] is Send then I need it to return what is currently in the SELECT statement above.
If [cfgSession].[SType] is Receive then I need it to return what is currently in the SELECT above minus the [cfgData] fields.

Related

How to a filter on the result on a stored procedure in DB2

I have a stored procedure in DB2 which returns a bunch of columns. I need to apply a 'WHERE' condition or do a sorting on one of the columns it returns. I don't want to touch the stored procedure and do this filtering/sorting when calling the stored procedure, something like below
select * from 'call SP1()' as T where T.column1 > 10
Is this possible in DB2?
Here is a deliberately artificial example of a pipelined UDF that filters the result-set of an SQLPL procedure.
In real world coding, most programmers will avoid filtering outside of stored-procedures, simply because it is easier and better performing, and more natural to filter at the earliest possible opportunity.
Tested on Db2-LUW v11.1.3.3 and 11.1.2.2 with DB2_COMPATIBILITY_MODE=ORA (or at least Bit-17 set to 1 as in 0x10000 , acknowledgement to P.Vernon for this clarification):
--#SET TERMINATOR #
create or replace procedure alltabs
dynamic result sets 1
language sql
specific alltabs
begin
declare v_cur cursor with return to caller for
select tabschema,tabname,type from syscat.tables ;
open v_cur;
end#
create or replace function allstatviews()
returns table (stat_view_name varchar(80))
begin
declare v_rs result_set_locator varying;
declare v_tabschema varchar(128);
declare v_tabname varchar(128);
declare v_type char(1);
declare sqlstate char(5) default '00000';
call alltabs;
associate result set locator (v_rs) with procedure alltabs;
allocate v_rscur cursor for result set v_rs;
fetch from v_rscur into v_tabschema, v_tabname, v_type;
while ( sqlstate = '00000') do
if v_type='V' and v_tabschema='SYSSTAT'
then
pipe(cast(rtrim(v_tabschema)||'.'||rtrim( v_tabname) as varchar(80)));
end if;
fetch from v_rscur into v_tabschema, v_tabname, v_type;
end while;
return;
end#
select * from table(allstatviews())
#

How to retrieve the input parameter values of a stored procedure

I want to create a auditing procedure which will be called in the catch block of all the procedure in my Database.
I wanted to store the list of all the input parameters and its values in this auditing DB.
Please suggest me, how to achieve this in SQL Server
I am not aware of programatically retrieving the list of parameters and their values for a stored proc(Possibly would involve n number of system tables and things like that). Without going into that level of complexity AND if altering the current procedures is a possibility, you could do something on the lines of below.
ALTER the existing stored procs to add a small functionality wherein you populate a table variable with
the parameters in a set string format('#paramname = paramvalue') and their values in the current proc
and then fire the Auditing proc if the control reaches the CATCH block.
--Add this code bit on top of the proc from where you want the Audit Proc to be fired
--Declare and insert into a table variable
Declare #ParamValues TABLE (params varchar(400))
insert into #ParamValues
select '#id = '+ #id UNION
select '#name = '+ #name UNION
select '#date = '+ #date
GO
...
....
END TRY
begin catch --Auditing proc code below
exec AuditDB.dbo.AuditProc #ParamValues,
OBJECT_NAME(##PROCID) --this returns the name of current proc
end catch
-------
-------Create the requisite SQL objects
-------
CREATE TABLE AuditDB.dbo.AuditTable
(
AuditMessage varchar(400),
ProcName varchar(200),
DateTimeStamp DateTime
);
GO
CREATE TYPE AuditDB.dbo.ParamValuesType AS TABLE
(
params varchar(400)
);
GO
CREATE PROCEDURE AuditDB.dbo.AuditProc
#ParamValues dbo.ParamValuesType READONLY
,#ProcName varchar(200)
AS
BEGIN --Add whaterver lines of code required, this is just a basic version.
INSERT INTO AuditDB.dbo.AuditTable
SELECT params, #ProcName, cast(getdate() as datetime) FROM #ParamValues
END;

How to work with more than one output parameter in single stored procedure

I have a SP with an Output parameter that looks like:
ALTER PROCEDURE [dbo].[SP_Name] #VarName decimal(18,2) OUTPUT as ...
I call that procedure from vb.net to get the value for calculations. My problem is: I have 8 SP's with the following structure:
CREATE PROCEDURE [dbo].[SP_Name] #VarName decimal(18,2) OUTPUT as ...
CREATE TABLE #TempTable
Begin
Select ...
End
SET #VarName = Result
But the TempTable is always the same. No I am looking for a way to get all 8 values with only one stored procedure. My idea:
CREATE PROCEDURE [dbo].[SP_Name] #VarName decimal(18,2) OUTPUT as ...
CREATE TABLE #TempTable
---Get first value
Begin
Select ...
End
SET #VarName1 = Result
---Get second value
Begin
Select ...
End
SET #VarName2 = Result
...
How do i have to rewrite the line: ALTER PROCEDURE [dbo].[SP_Name] #VarName decimal(18,2) OUTPUT ir can I even work with an array?
You can use a single stored procedure with all your queries in it. Following will return a single row result set with eight fields and you can grab them from your code using the specific filed name or index.
CREATE PROCEDURE [dbo].[SP_Name]
#VarName decimal(18,2)
AS
BEGIN
DECLARE #VarName1 Datatype, #VarName2 Datatype, ...#VarName8 Datatype
SELECT #VarName1 = yourCol
FROM --First query
SELECT #VarName2 = yourCol
FROM --Second query
...
SELECT #VarName8 = yourCol
FROM --Eighth query
--Finally Select all the variables
SELECT #VarName1 Col1, #VarName2 Col2, ...,#VarName8 Col8
END
OR if you are looking to return results of your all 8 queries, that is also possible. Simply do your select queries in a single stored procedure and grab the DATASET from your code and you can access individual table using zero based Index (ex DataTable1 = YourDataSet.Tables[0])

Oracle stored procedure error

Im a newbie to Oracle and trying to create a new procedure but getting a error,
Error-expression P_EMP_SAL cannot be used as an INTO target of SELECT/FETCH statement..
CREATE OR REPLACE PROCEDURE getempsal(
p_emp_id IN NUMBER,
p_emp_month IN CHAR,
p_emp_sal in INTEGER)
AS
BEGIN
SELECT EMP_SAL
INTO p_emp_sal
FROM EMPLOYEE_SAL
WHERE EMP_ID = p_emp_id
and EMP_MONTH = p_emp_month;
END getempsal;
You specify IN for a parameter you want to return from a procedure. Try p_emp_sal OUT INTEGER.
http://docs.oracle.com/cd/E11882_01/appdev.112/e25519/subprograms.htm#i4107
Take out put parameter refcursor
and make changes in body of procedure
Open outCursor for SELECT EMP_SAL
INTO p_emp_sal
FROM EMPLOYEE_SAL
WHERE EMP_ID = p_emp_id
and EMP_MONTH = p_emp_month;

Getting value from stored procedure in another stored procedure

Sorry, lots of code coming up..
I saw another question like this that used output parameters. I'm using the RETURN statement to return the value I want to use.
I have one stored procedure InsertMessage that looks like this:
ALTER PROCEDURE dbo.InsertNewMessage
(
#messageText text,
#dateTime DATETIME,
#byEmail bit,
#bySMS bit
)
AS
DECLARE #NewId int
BEGIN
BEGIN TRANSACTION
INSERT INTO MessageSet VALUES (#byEmail, #bySMS, #dateTime, #messageText)
SET #NewId = SCOPE_IDENTITY()
COMMIT
END
RETURN #NewId
which another stored procedure uses:
ALTER PROCEDURE dbo.InsertMessageFromUserToGroup
(
#userEmail nvarchar(256),
#groupId int,
#messageText text,
#bySMS bit,
#byEmail bit
)
AS
--Inserts a new message to a group
DECLARE #messageId int
DECLARE #dateTime DATETIME = GETDATE()
--First check if user is a part of the group
IF NOT EXISTS (SELECT userEmail FROM UserToGroupSet WHERE userEmail = #userEmail AND groupId = #groupId)
RETURN 'User not part of group'
ELSE --User is a part of the group, add message
BEGIN
BEGIN TRANSACTION
SET #messageId = [dbo].[InsertNewMessage](#messageText, #dateTime, #bySMS, #byEmail)
INSERT INTO MessageToUser VALUES(#userEmail, #messageId)
INSERT INTO MessageToGroup VALUES(#messageId, #groupId)
COMMIT
END
The row that causes the trouble and of which I'm unsure how to handle is this one:
SET #messageId = [dbo].[InsertNewMessage](#messageText, #dateTime, #bySMS, #byEmail)
The syntax seems ok because I can save it. When I run it I get the error message:
Running [dbo].[InsertMessageFromUserToGroup] ( #userEmail = test#test.com, #groupId = 5, #messageText = sdfsdf, #bySMS = false, #byEmail = true ).
Cannot find either column "dbo" or the user-defined function or aggregate "dbo.InsertNewMessage", or the name is ambiguous.
Transaction count after EXECUTE indicates a mismatching number of BEGIN and COMMIT statements. Previous count = 0, current count = 1.
No rows affected.
(0 row(s) returned)
#RETURN_VALUE =
Finished running [dbo].[InsertMessageFromUserToGroup].
It seems as if the other stored procedure can't be found. I've tried different ways of calling the procedure but everything else fails as well. Any suggestions?
Try changing
SET #messageId = [dbo].[InsertNewMessage](#messageText, #dateTime, #bySMS,
#byEmail)
to
EXEC #messageId = [dbo].[InsertNewMessage] #messageText, #dateTime, #bySMS,
#byEmail
Notice that SET has been changed to EXEC, and the parentheses have been removed from the parameters.
See the example in the MSDN documenation at the end of the article for more information.