'Dynamic' Stored Procedure - stored-procedures

I am very new to stored procedures and need some help.
I am trying to create a 'dynamic' stored procedure. When a parameter is NOT NULL then a certain part of the SQL should be added. This is what I have until now.
SELECT
TCId,
ENVId,
UId,
MTId,
TestSetName,
TestCaseName,
InterchangeSeqNo,
InstructionSeqNo,
TransactionSeqNo,
TestCaseDescription
FROM XML_TEST_SET_OVERVIEW
WHERE (ENVId = #MyENVId)
SELECT CASE #MyUId
WHEN IS NOT NULL THEN (AND UId = #MyUId)
END
SELECT CASE #MyMTId
WHEN IS NOT NULL THEN (AND MTId = #MyMTId)
END
SELECT CASE #MyTestSetName
WHEN IS NOT NULL THEN (AND TestSetName = #MyTestSetName)
END
SELECT CASE #MyTestCaseName
WHEN IS NOT NULL THEN (AND TestCaseName = #MyTestCaseName)
END
SELECT CASE #MyInterchangeSeqNo
WHEN IS NOT NULL THEN (AND InterchangeSeqNo = #MyInterchangeSeqNo)
END
SELECT CASE #MyInstructionSeqNo
WHEN IS NOT NULL THEN (AND InstructionSeqNo = #MyInstructionSeqNo)
END
SELECT CASE #MyTransactionSeqNo
WHEN IS NOT NULL THEN (AND TransactionSeqNo = #MyTransactionSeqNo)
END
ORDER BY ENVId, UId, MTId, TestSetName, TestCaseName, InterchangeSeqNo, InstructionSeqNo, TransactionSeqNo
Any help is appreciated

I have to guess at data types here, and I'll let you fill in the extra fluff.
DECLARE #sql NVARCHAR(MAX) = N'SELECT ...
FROM dbo.XML_TEST_SET_OVERVIEW -- always use schema prefix
WHERE ENVId = #MyENVId'
+ CASE WHEN #MyUId IS NOT NULL THEN
N' AND UId = #MyUId' ELSE '' END
+ CASE WHEN #MyMTId IS NOT NULL THEN
N' AND MTId = #MyMTId' ELSE '' END
+ CASE WHEN #MyTestSetName IS NOT NULL THEN
N' AND TestSetName = #MyTestSetName' ELSE '' END
...
+ CASE WHEN #MyTransactionSeqNo IS NOT NULL THEN
N' AND TransactionSeqNo = #MyTransactionSeqNo' ELSE '' END
+ N' ORDER BY ENVId, UId, ...;';
EXEC sp_executesql #sql,
N'#MyENVId INT, #MyUId INT, #MyMTId INT,
#MyTestSetName NVARCHAR(32), ... , #MyTransactionSeqNo INT',
#MyENVId, #MyUId, #MyMTId, #MyTestSetName, ... , #MyTransactioNSeqNo;

Related

Error: Query execution failed for dataset. Is my query correct for my dataset SSRS?

I'm trying to use SET,IF,ALTER TABLE. When i run the report it gives me a error 'Query execution failed for dataset'.
This is the query for the dataset:
declare #DOB date
declare #NO VARCHAR (30)
declare #ID VARCHAR(30)
set #DOB = #DOB
set #NO = #NO
set #ID =#ID
IF #DOB is null
begin
SELECT DISTINCT [Name]
into tempName
FROM [Patient]
where [No_]= #NO
or[Id No_] = #ID
END
else
IF #DH is null
begin
SELECT DISTINCT [Name]
into tempName
FROM [Patient]
where DATEOFBIRTH = #DOB
or [Id No_] = #ID
END
else
IF #ID is null
begin
SELECT DISTINCT [Name]
into tempName
FROM [Patient]
where [No_] = #NO
or DATEOFBIRTH = #DOB
end
ALTER TABLE tempName alter column Name varchar (30) NULL
INSERT INTO tempName (Name) values ('Nothing')
SELECT case Name
when '' then ''
when 'Nothing' then '*Nothing'
else Name
end Name
from tempName
order by [Name]
drop table tempName
Can someone help?
table "tempname" is an actual table or it's a temporary table? In the latter case you need to call it with #temptable

sql server stored proc returns only one row

I have an issue where only the last record in a csv file is written to the database by my stored procedure. I thought this might be related to the type of file (csv or text) because I have a comma delimited text file with only five records that will write all records, but when I used a csv file only the last record is written. I did read a post which said that this could be related to using a scalar variable in the stored proc but I don't think that this is right because when I use the text file it's still the same stored proc. Please advise.
Thanks!
here's the stored proc:
USE [SomeDB]
GO
/****** Object: StoredProcedure [dbo].[SaveUser] Script Date: 8/1/2016 9:25:24 AM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
Alter PROCEDURE [dbo].[SaveUser]
-- Add the parameters for the stored procedure here
#PartnerID INT,
#SourceID INT,
#OrgSourcedIDs NVARCHAR(50),
#Role NVARCHAR(50),
#UserID NVARCHAR(50),
#GivenName NVARCHAR(50),
#FamilyName NVARCHAR(50),
#Email NVARCHAR(50),
#Grade NVARCHAR(50),
#Identifier NVARCHAR(50)
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
DECLARE #ReturnVal NVARCHAR(10)
DECLARE #IsTransfer Bit = 0
DECLARE #IsUpdate BIT = 0
SELECT #IsTransfer = CASE WHEN OrgSourcedIDs != #OrgSourcedIDs THEN 1 ELSE 0 END,
#IsUpdate = CASE WHEN HASHBYTES('SHA', GivenName +FamilyName +Email +Grade ) != HASHBYTES('SHA', #GivenName + #FamilyName + #Email + #Grade ) THEN 1 ELSE 0 END
FROM dbo.tblUsers a
WHERE a.PartnerID = #PartnerID AND a.SourcedID = #SourceID
IF ##RowCount = 0
BEGIN
-- If not, add it to staging table with ACTION = INSERT (into tblUser)
INSERT INTO dbo.tblUsers
( PartnerID, SourcedID, OrgSourcedIDs, Role, UserID,
GivenName, FamilyName, Email, Grade, Identifier,
Action )
VALUES
( #PartnerID, #SourceID, #OrgSourcedIDs, #Role, #UserID,
#GivenName, #FamilyName, #Email, #Grade, #Identifier,
'Create' )
--SELECT #ReturnVal = 'INSERT'
END
ELSE IF (#IsTransfer = 1)
BEGIN
UPDATE dbo.tblUsers
SET
OrgSourcedIDs = #OrgSourcedIDs,
UserID = #UserID,
GivenName = #GivenName,
FamilyName = #FamilyName,
Email = #Email,
Grade = #Grade,
Identifier = #Identifier,
Action = 'Transfer'
WHERE
PartnerID = #PartnerID
AND SourcedID = #SourceID
END
ELSE IF(#IsUpdate = 1)
BEGIN
UPDATE dbo.tblUsers
SET
UserID = #UserID,
GivenName = #GivenName,
FamilyName = #FamilyName,
Email = #Email,
Grade = #Grade,
Identifier = #Identifier,
Action = 'Update'
WHERE
PartnerID = #PartnerID
AND SourcedID = #SourceID
END
--SELECT #ReturnVal
END
GO

Multiple condition WHERE clause returning unnecessary rows

In the stored procedure below, I'm wanting to return rows that do not have DEL in the Flag column. When I get the result back, the DEL rows are included. What am I doing wrong in my WHERE clause(I'm assuming that's what it is)?
ALTER PROCEDURE [dbo].[GetAllMessages]
-- Add the parameters for the stored procedure here
#Key varchar(30)
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for procedure here
SELECT message.msg_id,
message.tenant_id,
message.sender_id,
message.recipient_id,
message.recipient_email,
message.description,
message.date_recorded,
message.filename,
message.size_bytes,
message.size_time,
message.filepath,
message.Flag,
message.title,
message.date_activity,
member.member_image_url
FROM message
INNER JOIN member
ON message.sender_id = member.person_id
WHERE sender_id = (SELECT person_id FROM auth_key WHERE key = #Key)
OR recipient_id = (SELECT person_id FROM auth_key WHERE key = #Key)
AND Flag != 'DEL'
END
I suspect you need some extra parens to segment the logic in the manner you want:
WHERE (sender_id = (SELECT person_id FROM auth_key WHERE key = #Key)
OR recipient_id = (SELECT person_id FROM auth_key WHERE key = #Key))
AND Flag != 'DEL'

Rails migration error: Unicode string return null value inside "execute >> SQL"

I'm trying to do the things below in migration.
Split "Name" as splitted_name array.
SET first_name as splitted_name[0].
SET last_name as splitted_name[-1] if the splitted_name[0] and splitted_name[-1] were differnt.
SET last_name as empty string if the splitted_name[0] and splitted_name[1] are same.
Here is the code.
class ConvertNameIntoFirstAndLastName < ActiveRecord::Migration
def up
execute <<-SQL
DO
$do$
DECLARE
u record;
BEGIN
FOR u IN SELECT * FROM users LOOP
DECLARE
splitted_name text[];
BEGIN
splitted_name := CASE WHEN u.name IS NULL THEN '{''}'
ELSE regexp_split_to_array(u.name, E'\\s+')
END;
UPDATE users
SET
first_name = splitted_name[0],
last_name = CASE WHEN splitted_name[0] = splitted_name[-1] THEN ''
ELSE splitted_name[-1]
END,
name = splitted_name[0] || ' ' || (CASE WHEN splitted_name[0] = splitted_name[-1] THEN '{''}'
ELSE splitted_name[-1]
END)
WHERE id = u.id;
END;
END LOOP;
END;
$do$;
SQL
end
def down
end
end
The problem is u.name always return null when the name is unicode characters. The database encoding is set as Unicode.
Here is the error message.
PG::NotNullViolation: ERROR: null value in column "name" violates not-null constraint
=> The name is actually not null but some Unicode string.
Do you have any idea what is the cause of this error and how to solve this?
Sorry, I was so naive that I didn't know that I should use splitted_name[1] for the first_name and there's no array[-1].
This code worked.
class ConvertNameIntoFirstAndLastName < ActiveRecord::Migration
def up
execute <<-SQL
DO
$do$
DECLARE
u record;
BEGIN
FOR u IN SELECT * FROM users LOOP
DECLARE
splitted_name text[];
BEGIN
splitted_name := regexp_split_to_array(regexp_replace(u.name, ' ', ' '), ' ');
UPDATE users
SET
first_name = splitted_name[1],
last_name = CASE WHEN splitted_name[1] = splitted_name[array_upper(splitted_name, 1)] THEN ''
ELSE splitted_name[array_upper(splitted_name, 1)]
END,
name = splitted_name[1] || ' ' || (CASE WHEN splitted_name[1] = splitted_name[array_upper(splitted_name, 1)] THEN ''
ELSE splitted_name[array_upper(splitted_name, 1)]
END)
WHERE id = u.id;
END;
END LOOP;
END;
$do$;
SQL
end
def down
end
end

How to pass string parameter with `IN` operator in stored procedure SQL Server 2008

I have a stored procedure when I execute it I got error
Conversion failed when converting the varchar value '+#dptId+' to data type int
I am getting DepartmentId as a string like (1,3,5,77) and am passing this to my stored procedure.
SQL FIDDLE
create table dummy (id int,name varchar(100),DateJoining Datetime, departmentIt int)
insert into dummy values (1,'John','2012-06-01 09:55:57.257',1);
insert into dummy values(2,'Amit','2013-06-01 09:55:57.257',2);
insert into dummy values(3,'Naval','2012-05-01 09:55:57.257',3);
insert into dummy values(4,'Pamela','2012-06-01 09:55:57.257',4);
insert into dummy values(5,'Andrea','2012-09-01 09:55:57.257',3);
insert into dummy values(6,'Vicky','2012-04-01 09:55:57.257',4);
insert into dummy values(7,'Billa','2012-02-01 09:55:57.257',4);
insert into dummy values(8,'Reza','2012-04-01 09:55:57.257',3);
insert into dummy values (9,'Jacob','2011-05-01 09:55:57.257',5);
Query I tried:
declare #startdate1 varchar(100) ='20120201'
declare #enddate1 varchar(100)='20130601'
declare #dptId varchar(100)='3,4'
select *
from dummy
where DateJoining >= #startdate1 and DateJoining < #enddate1
and departmentIt IN (#dptId);
Here's how I solved it: Working SQL Fiddle
First I have create a function which splits the string value i.e. '1,2,4,5'
Split function:
CREATE FUNCTION fn_Split(#text varchar(8000), #delimiter varchar(20) = ' ')
RETURNS #Strings TABLE
(
position int IDENTITY PRIMARY KEY,
value varchar(8000)
)
AS
BEGIN
DECLARE #index int
SET #index = -1
WHILE (LEN(#text) > 0)
BEGIN
SET #index = CHARINDEX(#delimiter , #text)
IF (#index = 0) AND (LEN(#text) > 0)
BEGIN
INSERT INTO #Strings VALUES (#text)
BREAK
END
IF (#index > 1)
BEGIN
INSERT INTO #Strings VALUES (LEFT(#text, #index - 1))
SET #text = RIGHT(#text, (LEN(#text) - #index))
END
ELSE
SET #text = RIGHT(#text, (LEN(#text) - #index))
END
RETURN
END
Later in my query I use that split function
declare #startdate1 varchar(100) ='20120201'
declare #enddate1 varchar(100)='20130601'
declare #dptId varchar(100)='3,4'
select * from dummy
where DateJoining >=#startdate1 and DateJoining < #enddate1
and departmentID IN (SELECT Value FROM fn_Split(#dptId, ','));
Try using sp_executesql as the answer. Not the most efficient but it works
ALTER PROCEDURE [dbo].[uspTestReportData_GetBySerial]
#SerialNumbers nvarchar(200)
AS
BEGIN
SET NOCOUNT ON;
declare #sql nvarchar(200)
set #sql = 'SELECT * from MyTable WHERE Serial_Number in (' + #SerialNumbers + ')'
execute sp_executesql #sql
END
Simply, you can do the following SELECT:
SELECT M.REG_NO, T.TYPE_ID
FROM MAIN AS M
INNER JOIN CLASSIFICATION AS C
ON M.REG_NO = C.REG_NO
INNER JOIN TYPE AS T
ON T.TYPE_ID = C.TYPE_ID
WHERE (','+#Types+',') LIKE '%,' +T.TYPE_ID+ ',%'
ALTER PROCEDURE dbo.sp_Custom_Select_ClientVisit
(
#ClientVisitId int = Null,
#ClientId int = Null,
#PersonId int = Null,
#ProductId int = Null,
#VisitDateFrom datetime = Null,
#VisitDateTo datetime = Null,
#eVisitStatusIn varchar(100) = Null,
#eVisitStatus int = Null,
#eStatus int = Null,
#eStatusNot int = Null
)
AS
create table #IDs
(
Id int
)
Declare #delimiter varchar
Set #delimiter = ','
DECLARE #index int
SET #index = -1
WHILE (LEN(#eVisitStatusIn) > 0)
BEGIN
SET #index = CHARINDEX(#delimiter , #eVisitStatusIn)
IF (#index = 0) AND (LEN(#eVisitStatusIn) > 0)
BEGIN
INSERT INTO #IDs VALUES (#eVisitStatusIn)
BREAK
END
IF (#index > 1)
BEGIN
INSERT INTO #IDs VALUES (LEFT(#eVisitStatusIn, #index - 1))
SET #eVisitStatusIn = RIGHT(#eVisitStatusIn, (LEN(#eVisitStatusIn) - #index))
END
ELSE
SET #eVisitStatusIn = RIGHT(#eVisitStatusIn, (LEN(#eVisitStatusIn) - #index))
END
Select
ClientVisit.ClientVisitId, ClientVisit.eStatus,
ClientVisit.VisitTime, ClientVisit.VisitReason,
ClientVisit.eVisitStatus, ClientVisit.VisitSummary,
Client.ClientId, Client.InstituteName,
Client.PersonName as ClientPersonName, Client.eStatus as ClienteStatus,
Person.PersonId, Person.FirstName as ExecutiveFirstName, Person.LastName as ExecutiveLastName,
Person.FirstName + ' ' + Person.LastName as ExecutiveName,
p.ProductId, p.ParentProductId,
p.ProductName, p.Description as ProductDescription,
p.eStatus ProducteStatus,
Case When ClientVisit.eVisitStatus = 1 Then 'Pending'
When ClientVisit.eVisitStatus = 2 Then 'Completed'
When ClientVisit.eVisitStatus = 3 Then 'Cancelled' End As VisitStatus,
Case When ClientVisit.eStatus = 1 Then 'Active'
When ClientVisit.eStatus = 2 Then 'Deactive'
When ClientVisit.eStatus = 3 Then 'Deleted' End As Status
From AC_ClientVisit as ClientVisit
INNER Join Com_Client Client On Client.ClientId = ClientVisit.ClientId
INNER Join Com_Person Person On Person.PersonId = ClientVisit.ExecutiveId
INNER Join Com_Product p On p.ProductId = Client.RootProductId
Where
(#ClientVisitId IS NULL OR ClientVisit.ClientVisitId = #ClientVisitId)
AND (#ClientId IS NULL OR Client.ClientId = #ClientId)
AND (#PersonId IS NULL OR Person.PersonId = #PersonId)
AND (#ProductId IS NULL OR p.ProductId = #ProductId)
AND (#VisitDateFrom IS NULL OR #VisitDateFrom <= ClientVisit.VisitTime)
AND (#VisitDateTo IS NULL OR #VisitDateTo >= ClientVisit.VisitTime)
AND (#eVisitStatusIn IS NULL OR ClientVisit.eVisitStatus IN(SELECT i.Id FROM #IDs AS i))
AND (#eVisitStatus IS NULL OR ClientVisit.eVisitStatus = #eVisitStatus)
AND (#eStatus IS NULL OR ClientVisit.eStatus = #eStatus)
AND (#eStatusNot IS NULL OR ClientVisit.eStatus <> #eStatusNot)
RETURN

Resources