DB2 stored procedure w/ parameters - sql

I'm having a hard time producing the correct results from my stored procedure. I'm using a db2 database and I have 3 input parameters division, department, project. My call statement looks like this.
CALL schema.stored_procedure ('IT', 'MARKETING', 'ONLINE FULFILLMENT')
I need to produce results that will display the row of data when the third parameter is specified or has a value for the Project Name (as from the example above 'Online_fulfillment') and to display all the results when the third parameter has a value 'ALL' for Project Name (per the example below 'ALL').
CALL schema.stored_procedure ('IT', 'MARKETING', 'ALL')
My query below currently is returning just the column header names with no results and I'm having trouble debugging it. Here is my current stored procedure.
CREATE PROCEDURE schema.stored_procedure
(IN in_DIVISION_NAME VARCHAR(200)
,IN in_DEPARTMENT_NAME VARCHAR(20)
,IN in_PROJECT_NAME VARCHAR(400)
)
DYNAMIC RESULT SETS 1
BEGIN
IF (in_PROJECT_NAME = 'ALL') THEN
BEGIN
DECLARE GLOBAL TEMPORARY TABLE TEMP_DW_1
(DIM_PROJECT_ID INT
,PROJECT_NAME VARCHAR (400)
,DIM_DEPARTMENT_ID INT
,DEPARTMENT_NAME VARCHAR(100)
,DIVISION_NAME VARCHAR(100)
) ON COMMIT DELETE ROWS NOT LOGGED WITH REPLACE;
END;
INSERT INTO SESSION.TEMP_DW_1 (DIM_PROJECT_ID, PROJECT_NAME, DIM_DEPARTMENT_ID,
DEPARTMENT_NAME,DIVISION_NAME)
SELECT DISTINCT DJ.DIM_PROJECT_ID
,PROJECT_NAME
,DIM_DEPARTMENT_ID
,DEPARTMENT_NAME
,DIVISION_NAME
FROM SCHEMA.FACT_TABLE
WHERE DEPARTMENT_NAME = in_DEPARTMENT_NAME
AND DIVISION_NAME = in_DIVISION_NAME;
BEGIN
DECLARE exitCursor CURSOR WITH RETURN FOR
SELECT *
FROM SESSION.TEMP_DW_1;
OPEN exitCursor;
END;
END
EXPECTED RESULTS:
CALL schema.stored_procedure ('IT', 'MARKETING', 'ONLINE FULFILLMENT')
EXPECTED RESULTS:
CALL schema.stored_procedure ('IT', 'MARKETING', 'ALL')

I believe I have solved this by adding an additional IF statement setting the in_PROJECT_NAME <> 'ALL' and adding an additional filter to the second query that sets the PROJECT_NAME = in_PROJECT_NAME. Could be an easier way to solve this but it works:
IF (in_PROJECT_NAME <> 'ALL') THEN
BEGIN
DECLARE GLOBAL TEMPORARY TABLE TEMP_DW_1
(DIM_PROJECT_ID INT
,PROJECT_NAME VARCHAR (400)
,DIM_DEPARTMENT_ID INT
,DEPARTMENT_NAME VARCHAR(100)
,DIVISION_NAME VARCHAR(100)
) ON COMMIT DELETE ROWS NOT LOGGED WITH REPLACE;
END;
INSERT INTO SESSION.TEMP_DW_1 (DIM_PROJECT_ID, PROJECT_NAME, DIM_DEPARTMENT_ID,
DEPARTMENT_NAME ,DIVISION_NAME)
SELECT DISTINCT DJ.DIM_PROJECT_ID
,PROJECT_NAME
,DIM_DEPARTMENT_ID
,DEPARTMENT_NAME
,DIVISION_NAME
FROM SCHEMA.FACT_TABLE
WHERE DEPARTMENT_NAME = in_DEPARTMENT_NAME
AND DIVISION_NAME = in_DIVISION_NAME;
AND PROJECT_NAME = in_PROJECT_NAME

Related

stored procedure, handle possible null value

I have a very simple stored procedure which currently works perfectly when both parameters are sent values from form inputs.
However, I need to figure out what to do for IN_NUMBER if the value is empty because that column in the destination table is set to be nullable. It seems like the procedure itself is simply failing because it's waiting for a value.
What should I change?
IN parameters:
IN_NAME
IN_NUMBER
Routine:
P1 : BEGIN ATOMIC
INSERT INTO schema . postings
( name
, postNumber)
VALUES
( IN_NAME
, IN_NUMBER) ;
END P1
Example:
create table postings (name varchar(100), postNumber int) in userspace1#
create or replace procedure postings (
in_name varchar(100)
, in_number int
)
P1 : BEGIN ATOMIC
INSERT INTO postings
( name
, postNumber)
VALUES
( IN_NAME
, IN_NUMBER) ;
END P1#
call postings('myname', null)#
select * from postings#
NAME POSTNUMBER
---- ----------
myname <null>
There is no any problem here as you see.
What db2 error do you have exactly on a case similar to this?
If you want to handle NULL and replace it with some other value, use NVL(IN_NUMBER, 0) - you can exchange 0 for any other number of course (I'm assuming this is an integer).

Dynamic SQL (where) in Firebird stored procedure

I Have an SP that receive 2 parameters, P1 and P2, like this:
CREATE OR ALTER PROCEDURE MY_PROC (P1 varchar(10), P2 smallint = 1)
RETURNS (
code VARCHAR(10),
name VARCHAR(70),
state VARCHAR(2),
situation VARCHAR(20)
AS
...
...
And I need to generate the where clause based on the P2 parameter, like this:
if (P2=1) then
where (state='SP' and situation='stopped')
elseif (P2=2)
where (state='MG' and situation='moving')
How to use this type of if statement in where clause?
To me your question translates as a simple OR condition in the WHERE clause of a SQL query:
WHERE
(:P2 = 1 AND state='SP' and situation='stopped')
OR (:P2 = 2 AND state='MG' and situation='moving')
The answer of GMB will work fine for most situations, but in more complex cases it may have less desirable performance. An alternative solution would be to build a query string dynamically and execute it with execute statement:
CREATE OR ALTER PROCEDURE MY_PROC (P1 varchar(10), P2 smallint = 1)
RETURNS (
code VARCHAR(10),
name VARCHAR(70),
state VARCHAR(2),
situation VARCHAR(20)
AS
declare query varchar(2048);
begin
query = 'select ......';
if (p2 = 1) then
query = query || ' where (state=''SP'' and situation=''stopped'')';
else if (p2 = 2) then
query = query || ' where (state=''MG'' and situation=''moving'')';
-- if you expect a single result
execute statement query into code, name, state, situation;
-- OR
-- for multiple results
for execute statement query into code, name, state, situation do
suspend;
end

how to loop multipe variables in to one destination table using SSIS

I have three variables
#Emp = 'Select EmpName from Employee',
#Department = 'Select DeptName from Department',
#Customer = 'Select Custname from Customer'
and I have destination table
Output :
ID tbl_statement
1 Select EmpName from Employee
2 Select DeptName from Department
3 Select Custname from Customer
How can I loop these three variables into destination table using SSIS
I would propose you use an Execute SQL Task to store this data.
Given a target table such as the following
CREATE TABLE dbo.SO_53235748
(
ID int identity(1,1) NOT NULL
, tbl_statement nvarchar(max) NOT NULL
, AsOfDate datetime NOT NULL CONSTRAINT DF_dbo_SO_53235748 DEFAULT (GETDATE())
);
We'll use an OLE DB Connection and parameterize a query like this
INSERT INTO dbo.SO_53235748(tbl_statement)
SELECT D.tbl_statement
FROM
(
VALUES(?), (?), (?)
) D(tbl_statement);
The ? is a placeholder in the OLE DB Connection manager syntax. In the preceding query, it expects 3 parameters. In the event you have more or fewer parameters, then you would need to add/remove elements in the fifth line.
In the parameters tab, we will map based on ordinal positions, zero based, our variables into the parameters
Please try using For Each Variable looping in For Each Loop Task in SSis
Thanks

SQL procedure to add and edit data

Im busy with an old exam paper one of the questions read as follows
Study the following tables and answer the questions below:
CREATE TABLE CARDHOLDERS(
CH_ID INTEGER IDENTITY,
CH_NAME VARCHAR(50),
CH_SURNAME VARCHAR(50),
CH_IDNUMBER CHAR(13),
CH_CARDNUMBER CHAR(13),
CH_STATUS CHAR(2),
CH_CREATE_DATE DATETIME,
CH_LAST_CHANGE_DATE DATETIME)
Write a store procedure to add or edit the cardholders information. Do the neccecary validation checks to ensure data is correct.
My Answer
Create Procedure add_ch (#CH_NAME, #CH_SURNAME...)
AS
BEGIN
INSERT INTO CARDHOLDERS VALUES (#CH_NAME, #CH_SURNAME...)
END
TO RUN PROCEDURE
EXECUTE add_ch ('Peter', 'Kemp')
My Question
Will the above procedure to add cardholer give the correct results?
The Question asks 'Write a store procedure to add or edit the
cardholders information' how do I combine the add procedure with
the edit cardholder procedure or am I correct in assuming that I can
have to different procedure?
Are you looking for something like this?
CREATE PROCEDURE add_ch (#CH_NAME , #CH_SURNAME...)
AS
BEGIN
DECLARE #count INT
SET #count =
(SELECT count (*)
FROM CARDHOLDERS
WHERE CH_NAME = #CH_NAME AND CH_SURNAME = #CH_SURNAME)
IF #count = 0
INSERT INTO CARDHOLDERS
VALUES (#CH_NAME, #CH_SURNAME...)
else Print'This user already exsit.'
END
Try something like this. Using decode and setting defaults for the parameters helps.
create or replace procedure add_ch
(
CHID INTEGER := -1,
CHNAME VARCHAR := '#',
CHSURNAME VARCHAR := '#',
CHIDNUMBER CHAR := '#',
CH_CARDNUMBER CHAR := '#',
CHSTATUS CHAR := '#',
CHCREATE_DATE DATETIME := '01-Jan-1900',
CHLAST_CHANGE_DATE DATETIME:= '01-Jan-1900'
)
as
begin
update cardholders
set CH_NAME = decode( CHNAME,'#',CH_NAME,chname ),
CH_SURNAME = decode( CHSURNAME,'#',CH_SURNAME, CHSURNAME),....
where CH_ID = CHID;
if sql%notfound
then
insert into cardholders
(
CH_ID,
CH_NAME,
CH_SURNAME,
CH_IDNUMBER,
CH_CARDNUMBER,
CH_STATUS,
CH_CREATE_DATE,
CH_LAST_CHANGE_DATE
)
values
(
CHID,
CHNAME,
CHSURNAME,
CHIDNUMBER,
CH_CARDNUMBER,
CHSTATUS CHAR,
CHCREATE_DATE,
CHLAST_CHANGE_DATE
);
end;
first of all You Have to find The primary key data in your database table
if exist data in DBtable(with current primary key value)
then execute your update sql query
else
execute your insert query.
Done your database checking using the previous answer to your question.

How to pass multiple values to single parameter in stored procedure

I'm using SSRS for reporting and executing a stored procedure to generate the data for my reports
DECLARE #return_value int
EXEC #return_value = [dbo].[MYREPORT]
#ComparePeriod = 'Daily',
#OverrideCompareDate = NULL,
#PortfolioId = '5,6',
#OverrideStartDate = NULL,
#NewPositionsOnly = NULL,
#SourceID = 13
SELECT 'Return Value' = #return_value
GO
In the above when I passed #PortfolioId = '5,6' it is giving me wrong inputs
I need all records for portfolio id 5 and 6 also is this correct way to send the multiple values ?
When I execute my reports only giving #PortfolioId = '5' it is giving me 120 records
and when I execute it by giving #PortfolioId = '6' it is giving me 70 records
So when I will give #PortfolioId = '5,6' it should have to give me only 190 records altogether, but it is giving me more no of records I don't understand where I exactly go wrong .
Could anyone help me?
thanks
all code is too huge to paste , i'm pasting relevant code please suggest clue.
CREATE PROCEDURE [dbo].[GENERATE_REPORT]
(
#ComparePeriod VARCHAR(10),
#OverrideCompareDate DATETIME,
#PortfolioId VARCHAR(50) = '2', --this must be multiple
#OverrideStartDate DATETIME = NULL,
#NewPositionsOnly BIT = 0,
#SourceID INT = NULL
) AS
BEGIN
SELECT
Position.Date,
Position.SecurityId,
Position.Level1Industry,
Position.MoodyFacilityRating,
Position.SPFacilityRating,
Position.CompositeFacilityRating,
Position.SecurityType,
Position.FacilityType,
Position.Position
FROM
Fireball_Reporting.dbo.Reporting_DailyNAV_Pricing POSITION WITH (NOLOCK, READUNCOMMITTED)
LEFT JOIN Fireball.dbo.AdditionalSecurityPrice ClosingPrice WITH (NOLOCK, READUNCOMMITTED) ON
ClosingPrice.SecurityID = Position.PricingSecurityID AND
ClosingPrice.Date = Position.Date AND
ClosingPrice.SecurityPriceSourceID = #SourceID AND
ClosingPrice.PortfolioID IN (
SELECT
PARAM
FROM
Fireball_Reporting.dbo.ParseMultiValuedParameter(#PortfolioId, ',') )
This can not be done easily. There's no way to make an NVARCHAR parameter take "more than one value". What I've done before is - as you do already - make the parameter value like a list with comma-separated values. Then, split this string up into its parts in the stored procedure.
Splitting up can be done using string functions. Add every part to a temporary table. Pseudo-code for this could be:
CREATE TABLE #TempTable (ID INT)
WHILE LEN(#PortfolioID) > 0
BEGIN
IF NOT <#PortfolioID contains Comma>
BEGIN
INSERT INTO #TempTable VALUES CAST(#PortfolioID as INT)
SET #PortfolioID = ''
END ELSE
BEGIN
INSERT INTO #Temptable VALUES CAST(<Part until next comma> AS INT)
SET #PortfolioID = <Everything after the next comma>
END
END
Then, change your condition to
WHERE PortfolioId IN (SELECT ID FROM #TempTable)
EDIT
You may be interested in the documentation for multi value parameters in SSRS, which states:
You can define a multivalue parameter for any report parameter that
you create. However, if you want to pass multiple parameter values
back to a data source by using the query, the following requirements
must be satisfied:
The data source must be SQL Server, Oracle, Analysis Services, SAP BI
NetWeaver, or Hyperion Essbase.
The data source cannot be a stored procedure. Reporting Services does
not support passing a multivalue parameter array to a stored
procedure.
The query must use an IN clause to specify the parameter.
This I found here.
I spent time finding a proper way. This may be useful for others.
Create a UDF and refer in the query -
http://www.geekzilla.co.uk/view5C09B52C-4600-4B66-9DD7-DCE840D64CBD.htm
USE THIS
I have had this exact issue for almost 2 weeks, extremely frustrating but I FINALLY found this site and it was a clear walk-through of what to do.
http://blog.summitcloud.com/2010/01/multivalue-parameters-with-stored-procedures-in-ssrs-sql/
I hope this helps people because it was exactly what I was looking for
Either use a User Defined Table
Or you can use CSV by defining your own CSV function as per This Post.
I'd probably recommend the second method, as your stored proc is already written in the correct format and you'll find it handy later on if you need to do this down the road.
Cheers!
I think, below procedure help you to what you are looking for.
CREATE PROCEDURE [dbo].[FindEmployeeRecord]
#EmployeeID nvarchar(Max)
AS
BEGIN
DECLARE #sqLQuery VARCHAR(MAX)
Declare #AnswersTempTable Table
(
EmpId int,
EmployeeName nvarchar (250),
EmployeeAddress nvarchar (250),
PostalCode nvarchar (50),
TelephoneNo nvarchar (50),
Email nvarchar (250),
status nvarchar (50),
Sex nvarchar (50)
)
Set #sqlQuery =
'select e.EmpId,e.EmployeeName,e.Email,e.Sex,ed.EmployeeAddress,ed.PostalCode,ed.TelephoneNo,ed.status
from Employee e
join EmployeeDetail ed on e.Empid = ed.iEmpID
where Convert(nvarchar(Max),e.EmpId) in ('+#EmployeeId+')
order by EmpId'
Insert into #AnswersTempTable
exec (#sqlQuery)
select * from #AnswersTempTable
END