Multiple condition WHERE clause returning unnecessary rows - stored-procedures

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'

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

'Dynamic' Stored Procedure

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;

NOT EXISTS SQL query in rails 3.2

I have an sql query like this:-
SELECT * FROM `permissions` join entities where NOT EXISTS (select
entity_id,permission_id from role_permissions where role_id=5 and
entities.id = role_permissions.entity_id and permissions.id =
role_permissions.permission_id)
I would like to get the corresponding rails query.
I have tried this.
Permission.joins("join entities").joins("LEFT OUTER JOIN role_permissions on
permission_id != permissions.id and entities.id != entity_id and
role_permissions.role_id= role_id").select("role_permissions.entity_id,role_permissions.role_id,
role_permissions.permission_id").group('role_permissions.entity_id,
role_permissions.permission_id')
But it doesn't works.
thanks
hari
I have been particularly in love with EXISTS queries lately, precisely because it does not require you to fully join another table. As far as I know, you do have to explicitly write the SQL clause, but you can still make it work with Activerecord. You can even put this in a scope within a lambda block.
Permission.joins(:entities).where(<<-SQL
NOT EXISTS(
select
* from role_permissions where role_id=#{your_role_id} and
entities.id = role_permissions.entity_id
and permissions.id = role_permissions.permission_id
)
SQL
)
Try like this for a default SQL query:
sql = "SELECT some_field FROM `permissions` join entities where NOT EXISTS (select entity_id,permission_id from role_permissions where role_id=5 and entities.id = role_permissions.entity_id and permissions.id = role_permissions.permission_id)"
results = ActiveRecord::Base.connection.execute(sql)
results.each do |result|
#register_users << { some_field: result[0] }
end
Try this
UPDATED BASED ON FIRST COMMENT
Permission.joins(:entities).joins("LEFT OUTER JOIN role_permissions on
permission_id != permissions.id and entities.id != entity_id and
role_permissions.role_id= role_id")
.select("role_permissions.entity_id,role_permissions.role_id,
role_permissions.permission_id")
.group('role_permissions.entity_id, role_permissions.permission_id')

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