Unable to Update the Records in the Table - sql

I am trying to update values from one table to another. SQL Server is showing 1 row(s) affected. But records do not get updated.
This is the Merge update I am using:
MERGE dbo.Patients p
USING #Patient_Already_in_System s
ON p.PatientID = s.PatientID
WHEN MATCHED AND s.Student_ID = 165364
THEN UPDATE
SET FirstName = CAST(SUBSTRING(s.Client_First_Name,1,25) AS VARCHAR(25))
,LastName = CAST(SUBSTRING(s.Client_Last_Name,1,35) AS VARCHAR(35))
,MiddleName = CAST(s.Student_ID AS VARCHAR(25))
,Street = CAST(s.Address AS VARCHAR(100))
,StateID = CAST(s.State AS CHAR(2))
,ZipCode = CAST(s.Zip AS varchar(10))
,Gender = ( SELECT id FROM dbo.lkpGenderIdentityExym WHERE id = s.gender)
,DOB = CAST(s.DOB AS DATETIME)
,Hispanic = CASE WHEN s.Ethnicity2 = 'No, not Hispanic or Latino' THEN CAST(0 AS BIT)
WHEN s.Ethnicity2 = 'Yes, Hispanic or Latino' THEN CAST(1 AS BIT)
ELSE NULL
END
,GradeLevel = CAST(s.grade AS VARCHAR(25))
,RaceID = (SELECT ID FROM dbo.lkpRace WHERE DMHDescriptionForCSIRace = s.race)
,Location = (SELECT id FROM dbo.Locations WHERE Description LIKE s.Location OR Description LIKE s.Location + ' High')
,AssignedToID = CASE WHEN (SELECT id FROM dbo.lkpUsers WHERE FullName = s.Primary_Therapist) IS NULL THEN 809 -- Z-EXYM-Malik Qayyum
ELSE (SELECT id FROM dbo.lkpUsers WHERE FullName = s.Primary_Therapist)
END;
I have also tried a regular UPDATE Table Set ..... Same thing. Any pointers on what I am missing?

Related

CASE WHEN to assign a result set to a query

I've been trying to assign different resultsets to a query depending on an input
Depending on the company selected a set of filtered results should be displayed, here's my code.
DECLARE #COMPANY VARCHAR(10) = 'Company_name1'
SELECT
(CASE
WHEN #COMPANY = 'Company_name1'
THEN (SELECT INVENTLOCATIONID FROM INVENTDIM INV
WHERE (INV.DATAAREAID = #COMPANY)
AND (((INVENTLOCATIONID IS NOT NULL)
AND ((WMSLOCATIONID IS NOT NULL)
AND (WMSLOCATIONID <> '')))
AND (INV.INVENTLOCATIONID = 'x5'))
WHEN #COMPANY = 'Company_name2'
THEN (SELECT INVENTLOCATIONID FROM INVENTDIM INV
WHERE (INV.DATAAREAID = #COMPANY)
AND (((INVENTLOCATIONID IS NOT NULL)
AND ((WMSLOCATIONID IS NOT NULL)
AND (WMSLOCATIONID <> '')))
AND (INVENTLOCATIONID IN ('X0', 'X1', 'X2', 'X3', 'X5', 'X6', 'X8', 'P6', 'P8')))
ELSE (SELECT INVENTLOCATIONID FROM INVENTDIM INV
WHERE (DATAAREAID = #COMPANY)
AND ((INVENTLOCATIONID IS NOT NULL)
AND ((WMSLOCATIONID IS NOT NULL)
AND (WMSLOCATIONID <> '')))
END) AS WHAREWOUSE
FROM
INVENTDIM INV
ORDER BY
INV.INVENTLOCATIONID
Why am I not allowed to do this?
Here's one way you could do this using a CASE expression. Use a constant to reject entries where the company name matches the specific cases and the location is not in your list. If the company isn't one of the special cases, then accept it.
DECLARE #COMPANY VARCHAR(10) = 'Company_name1';
SELECT WHAREHOUSE = INVENTLOCATIONID
FROM dbo.INVENTDIM
WHERE DATAAREAID = #COMPANY
AND INVENTLOCATIONID IS NOT NULL
AND WMSLOCATIONID IS NOT NULL
AND WMSLOCATIONID <> ''
AND 1 =
(
CASE
WHEN DATAAREAID = 'Company_name1'
AND INVENTLOCATIONID <> 'x5'
THEN 0
WHEN DATAAREAID = 'Company_name2'
AND INVENTLOCATIONID NOT IN ('X0','X1','X2','X3','X5','X6','X8','P6','P8')
THEN 0
ELSE 1
END
)
ORDER BY INVENTLOCATIONID;
Potentially a disaster for query plan reuse, though, unless DATAAREAID is unique.
This is definitely a better approach:
Can you create a new cross reference table to allow the database to map company to the inventlocationid? – Zynon Putney II
So say you had a mapping table like:
CREATE TABLE dbo.LocationMap
(
DATAAREAID varchar(10),
INVENTLOCATIONID char(2),
PRIMARY KEY(DATAAREAID, INVENTLOCATIONID
);
INSERT dbo.LocationMap(DATAAREAID,INVENTLOCATIONID)
VALUES
('Company_Name1', 'x5'),
('Company_Name2', 'X0'), ('Company_Name2', 'X1') -- , ...
Then your query becomes:
DECLARE #COMPANY VARCHAR(10) = 'Company_name1';
SELECT WHAREHOUSE = INV.INVENTLOCATIONID
FROM dbo.INVENTDIM AS INV
LEFT OUTER JOIN dbo.LocationMap AS lm
ON INV.DATAAREAID = lm.DATAAREAID
WHERE INV.DATAAREAID = #COMPANY
AND INV.INVENTLOCATIONID IS NOT NULL
AND INV.WMSLOCATIONID IS NOT NULL
AND INV.WMSLOCATIONID <> ''
AND (lm.INVENTLOCATIONID = INV.INVENTLOCATIONID
OR lm.DATAAREAID IS NULL)
ORDER BY INV.INVENTLOCATIONID;
Written as a single query this is equivalent logic. Depending on the size of your data it's possible that the if..else branching would work better.
SELECT INVENTLOCATINID
FROM INVENTDIM INV
WHERE
INV.DATAAREAID = #COMPANY AND INVENTLOCATIONID IS NOT NULL WMSLOCATIONID <> '' AND
(
#COMPANY = 'Company name1' AND INV.INVENTLOCATIONID = 'x5' OR
#COMPANY = 'Company_name2' AND INVENTLOCATIONID IN
('X0', 'X1','X2','X3','X5','X6','X8','P6','P8') OR
#COMPANY NOT IN ('Company name1', 'Company name2')
);
Try this below query to get desired output
DECLARE #COMPANY VARCHAR(10) = 'Company_name1'
declare #tblIL as table
(
INVENTLOCATIONID int
)
IF(#COMPANY = 'Company_name1')
BEGIN
insert into #tblIL(INVENTLOCATIONID) values ('x5')
END
ELSE IF(#COMPANY = 'Company_name2')
BEGIN
insert into #tblIL(INVENTLOCATIONID) values ('X0', 'X1','X2','X3','X5','X6','X8','P6','P8')
END
ELSE
BEGIN
insert into #tblIL(INVENTLOCATIONID) values SELECT DISTINCT INVENTLOCATIONID FROM INVENTDIM
END
SELECT INVENTLOCATIONID FROM INVENTDIM INV
WHERE INV.DATAAREAID = #COMPANY AND INVENTLOCATIONID IS NOT NULL AND WMSLOCATIONID IS NOT NULL AND WMSLOCATIONID <> ''
AND INV.INVENTLOCATIONID in (select INVENTLOCATIONID from #tblIL)

SQL Server: Update, set a value that is within another select

I have the following query:
update UpdCmmPartnerArticleGroup
set IsActive = 1,
Name = a.GroupName
from
(
select t.Name as GroupName
from #ArticleGroupsTable t
left join UpdCmmPartnerArticleGroup s on s.PartnerID=t.PartnerID and s.Name=t.Name
where s.PartnerID is null
) a
where Name = '' and IsActive = 0
It's purpose is to take a list of GroupNames and assign them to the UpdCmmPartnerArticleGroup.Name field. The list has 8 values and it uses only the first and the last to update.
What am I doing wrong, it looks pretty straight forward, but it's behavior is strange.
You can use a little bit simplified version.
UPDATE u
SET IsActive = 1, Name = t.Name
FROM #ArticleGroupsTable t
LEFT JOIN UpdCmmPartnerArticleGroup u
ON u.PartnerID=t.PartnerID AND u.Name=t.Name
WHERE u.Name = '' and u.IsActive = 0 and u.PartnerID IS NULL
Why not use subquery
update s
set IsActive = 1,
Name = (select t.Name from #ArticleGroupsTable t WHERE s.PartnerID=t.PartnerID and s.Name=t.Name AND s.PartnerID is null)
from UpdCmmPartnerArticleGroup s
where Name = '' and IsActive = 0
Try this,
UPDATE s
SET s.IsActive = 1
,s.NAME = t.NAME
FROM #ArticleGroupsTable t
LEFT JOIN UpdCmmPartnerArticleGroup s ON s.PartnerID = t.PartnerID
AND s.NAME = t.NAME
WHERE s.PartnerID IS NULL
AND s.NAME = ''
AND s.IsActive = 0
Try this:
IF OBJECT_ID('tempdb..#UpdCmmPartnerArticleGroup') IS NOT NULL
DROP TABLE #UpdCmmPartnerArticleGroup;
IF OBJECT_ID('tempdb..#ArticleGroupsTable') IS NOT NULL
DROP TABLE #ArticleGroupsTable;
CREATE TABLE #UpdCmmPartnerArticleGroup
(
PartnerId INT IDENTITY(1, 1)
,Name VARCHAR(50)
,IsActive BIT
);
INSERT INTO [#UpdCmmPartnerArticleGroup]
( [Name], [IsActive] )
VALUES ( 'Test1' -- Name - varchar(50)
, 1 -- IsActive - bit
),
( 'Test2' -- Name - varchar(50)
, 0 -- IsActive - bit
),
( '' -- Name - varchar(50)
, 0 -- IsActive - bit
);
CREATE TABLE #ArticleGroupsTable
(
PartnerId INT
,Name VARCHAR(50)
);
INSERT INTO [#ArticleGroupsTable]
( [PartnerId], [Name] )
VALUES ( 1, 'Test1' ),
( 2, 'Test2' ),
( 4, 'Test4' );
SELECT *
FROM [#UpdCmmPartnerArticleGroup];
SELECT *
FROM [#ArticleGroupsTable];
UPDATE [#UpdCmmPartnerArticleGroup]
SET [IsActive] = 1
, [Name] = (
SELECT t.[Name] AS GroupName
FROM [#ArticleGroupsTable] t
LEFT JOIN [#UpdCmmPartnerArticleGroup] s
ON [s].[PartnerId] = [t].[PartnerId]
AND [s].[Name] = [t].[Name]
WHERE [s].[PartnerId] IS NULL
)
WHERE [#UpdCmmPartnerArticleGroup].[Name] = ''
AND [IsActive] = 0;
SELECT *
FROM [#UpdCmmPartnerArticleGroup];

SQL Server processing for jquery datatables order by issue?

I have written the following script to mimic the incoming parameters from datatables and try to filter the results using the parameters. Everything works fine except the order by clause. Basically it only orders by rownumber and does not take into consideration the case statement which provides the second order by column.
declare #sSortColumn as nvarchar(50)='Country';
declare #sSortDirection as nvarchar(5) = 'Desc';
declare #sSearch as nvarchar(50) = '';
declare #iDisplayLength as int = 20;
declare #iDisplayStart as int = 20;
declare #sIDsearch as int = CASE WHEN ISNUMERIC(#sSearch) = 1 THEN CAST(#sSearch AS INT) ELSE 0 END;
WITH media AS
(
select ROW_NUMBER() OVER (ORDER BY mc.id) as RowNumber,
mc.id,mc.Name, mc.CityID,lc.Name as Country
from Lookup_MediaChannels mc
left join Lookup_SonarMediaTypes st on mc.SonarMediaTypeID = st.ID
left join Lookup_SonarMediaGroups sg on sg.ID = st.SonarMediaGroupID
left join Lookup_MediaTypes mt on mc.MediaTypeID = mt.ID
left join Lookup_SonarMediaGroups sg1 on sg1.ID = mt.MediaGroupID
left join lookup_Countries lc on lc.id = mc.countryid
where mc.Name like '%'+#sSearch+'%'
and (sg1.ID=1 or sg.ID =1 )
or mc.id = #sIDsearch
)
SELECT RowNumber, Name, Country
FROM media
WHERE RowNumber BETWEEN (#iDisplayStart+ 1) AND (#iDisplayStart+ #iDisplayLength)
order by rownumber,
CASE WHEN #sSortColumn = 'Name' AND #sSortDirection = 'Desc'
THEN Name END DESC,
CASE WHEN #sSortColumn = 'Name' AND #sSortDirection != 'Desc'
THEN Name END,
CASE WHEN #sSortColumn = 'Country' AND #sSortDirection = 'Desc'
THEN Country END DESC,
CASE WHEN #sSortColumn = 'Country' AND #sSortDirection != 'Desc'
THEN Country END
This simplified example may help you
http://sqlfiddle.com/#!6/35ffb/10
Set up some dummy data (this would be replaced by your select statement)
create table x(
id int,
name varchar(3),
country varchar(2)
)
insert into x
values (1,'aaa','uk'),
(2,'aaa','us'),
(3,'baa','uk'),
(4,'caa','uk'),
(5,'baa','it')
Some vars to hold sort field and sort order
declare #so char(1)
declare #sf char(1)
set #so = 'a' -- a = asc d = desc
set #sf = 'n' -- n = name c = country
and a select to return sorted data
SELECT row_number()
OVER (order by
CASE WHEN #so = 'd' THEN sf END desc,
CASE WHEN #so <> 'd' THEN sf end,
id
) AS aa, name,country
FROM (
SELECT x.*, case #sf when 'n' then name when 'c' then country end sf
FROM X
) X

Speeding up this query? Currently it takes 4 seconds on 100K rows

This is my main query:
exec sp_executesql N'set arithabort off;set transaction isolation level read uncommitted;Select COUNT(*) From ( Select ROW_NUMBER() OVER
(Order By Case When d.OldInstrumentID IS NULL THEN d.LastStatusChangedDateTime Else d.RecordingDateTime End desc ) peta_rn,
d.DocumentID
From Documents d
Inner Join Users u on d.UserID = u.UserID Inner Join IGroupes ig on ig.IGroupID = d.IGroupID
Inner Join ITypes it on it.ITypeID = d.ITypeID Where 1=1 ANd dbo.DoesNameExist(d.DocumentID, #0, #1, #2, #3) = 1 And (CreatedByAccountID = #4
Or DocumentStatusID = #5
Or DocumentStatusID = #6 ) )
v',N'#0 int,#1 varchar(4000),#2 varchar(4000),#3 nvarchar(4000),#4 int,#5 int,#6 int',#0=-999,#1='K',#2='Miller',
#3=NULL,#4=44,#5=5,#6=9
and this is my scalar function which is the culprit:
ALTER FUNCTION [dbo].[DoesNameExist]
(
#DocumentID int,
#PartyTypeID int = 0,
#FirstName varchar(30),
#LastName varchar(30),
#Business varchar(100)
)
RETURNS bit
AS
BEGIN
Declare #Found bit = 0
Set #FirstName = IsNull(#FirstName,'')
Set #LastName = IsNull(#LastName,'')
Set #Business = IsNull(#Business,'')
Select Top 1 #Found = 1
From DocumentNames
Where DocumentID = #DocumentID
And
Lower(IsNull(FirstName,'')) Like
Case When #FirstName = '' Then Lower(IsNull(FirstName,'')) + '%'
Else Lower(#FirstName) + '%' End
And
Lower(IsNull(LastName,'')) Like
Case When #LastName = '' Then Lower(IsNull(LastName,'')) + '%'
Else Lower(#LastName) + '%' End
And
Lower(IsNull(Business,'')) Like
Case When #Business = '' Then Lower(IsNull(Business,'')) + '%'
Else Lower(#Business) + '%' End
And
PartyTypeID = Case When #PartyTypeID IS NULL OR #PartyTypeID <= 0 Then PartyTypeID Else #PartyTypeID End
Return #Found
END
Basically one document has multiple DocumentNames and when the user types something in LastName or FirstName, I want to bring the count of all documents which have those matching names. Please note, I am querying on Documents table and then joining to DocumentNames. This is necessary.
Note: Indexes are created on all search columns which include FirstName, LastName etc.
Thanks!
First, check Execution plan. How may times IsNULL() is getting used?Check estimated and actual time taken for all IsNULL(). If it is more, use a subquery where you can just calculate IsNULL() and supply to your query.
I do not have your Exceution plan. You can also try this aswell :
ALTER FUNCTION [dbo].[DoesNameExist]
(
#DocumentID int,
#PartyTypeID int = 0,
#FirstName varchar(30),
#LastName varchar(30),
#Business varchar(100)
)
RETURNS bit
AS
BEGIN
Declare #Found bit = 0
Select Top 1 #Found = 1
From DocumentNames
Where DocumentID = #DocumentID
And
Lower(IsNull(FirstName,'')) Like COALESCE(#FirstName,firstname,'')+'%'
And
Lower(IsNull(LastName,'')) Like COALESCE(#LastName,LastName,'')+'%'
And
Lower(IsNull(Business,'')) Like COALESCE(#Business,Business,'')+'%'
And
PartyTypeID = Case When #PartyTypeID IS NULL OR #PartyTypeID <= 0 Then PartyTypeID Else #PartyTypeID End
Return #Found
END
Also if you are ok to discard this UDF, using this directly in your statement with EXISTS clause should do the trick.
Select COUNT(*) From ( Select ROW_NUMBER() OVER
(Order By Case When d.OldInstrumentID IS NULL THEN d.LastStatusChangedDateTime Else d.RecordingDateTime End desc ) peta_rn,
d.DocumentID
From Documents d
Inner Join Users u on d.UserID = u.UserID Inner Join IGroupes ig on ig.IGroupID = d.IGroupID
Inner Join ITypes it on it.ITypeID = d.ITypeID Where 1=1
ANd EXISTS (
Select 1
From DocumentNames
Where DocumentID = d.DocumentID
And
Lower(IsNull(FirstName,'')) Like COALESCE(#1,lower(firstname),'')+'%'
And
Lower(IsNull(LastName,'')) Like COALESCE(#2,lower(LastName),'')+'%'
And
Lower(IsNull(Business,'')) Like COALESCE(#3,lower(Business),'')+'%'
And
PartyTypeID = Case When #0 IS NULL OR #0 <= 0 Then PartyTypeID Else #0 End
)
Or DocumentStatusID = #5
Or DocumentStatusID = #6 ) )
v',N'#0 int,#1 varchar(4000),#2 varchar(4000),#3 nvarchar(4000),#4 int,#5 int,#6 int',#0=-999,#1='K',#2='Miller',
#3=NULL,#4=44,#5=5,#6=9

Write a query to swap values in a table in SQL Server?

I have mistakenly inserted wrong data in table rows, now I want to swap the data.
Male in place of Female and vice-versa.
Following is the correct data I am expecting -
Simple update works:
UPDATE myTable
SET
col1 = CASE WHEN col1 = 'male' THEN 'female' ELSE 'male' END,
col2 = CASE WHEN col2 = 'female' THEN 'male' ELSE 'female' END
Result: row values will be swap.
I hope, It will work for you.
You could use:
UPDATE table_name
SET Gender = CASE Gender
WHEN 'Male' THEN 'Female'
WHEN 'Female' THEN 'Male'
ELSE Gender
END;
LiveDemo
Please note that other values than male/female like N/A or NULL will remain the same.
If you want to do it only for specified names use:
UPDATE table_name
SET Gender = CASE
WHEN Name IN ('Geetha', 'Radha') THEN 'Female'
WHEN Name IN ('Ram', 'Syam', 'Ravi') THEN 'Male'
END
WHERE Name IN ('Ram', 'Syam', 'Geetha', 'Radha', 'Ravi');
I don't understand why you want a temp table if you can do it with a single update
But maybe this fits what you are looking for
SELECT TOP 0 *
INTO #tmp
FROM YourTable
UPDATE T
SET gender = 'male'
OUTPUT Inserted.* INTO #tmp
FROM YourTable T
WHERE gender = 'female'
UPDATE T
SET gender = 'female'
FROM YourTable
WHERE gender = 'male' --Irrelevant for this case but assuming that you have different values
AND NOT EXISTS (SELECT 1 FROM #Temp WHERE name = T.name) -- Exclude the "swapped" records
Or maybe you just want a temp table to confirm the changes before update them.... i am trying to guess
DECLARE #swap1 VARCHAR(20) = 'male', #swap2 VARCHAR(20) = 'female'
SELECT *
INTO #tmp
FROM YourTable
UPDATE #tmp
SET gender = CASE
WHEN gender = #swap1 THEN #swap2
WHEN gender = #swap2 THEN #swap1
ELSE gender END
SELECT * FROM #tmp
UPDATE A
SET Gender = T.gender
FROM YourTable A
JOIN #tmp T ON A.name = T.name
DROP TABLE #tmp
Use below script to swap values between 2 rows
IF OBJECT_ID('tempdb..#TempTable') IS NOT NULL DROP TABLE #TempTable
CREATE TABLE #TempTable
(
ROW_ID INT IDENTITY(1,1),
SEQUENCE_NO INT,
ID INT
)
DECLARE #Id INT = 24780, --Row Id
DECLARE #NewPosition INT = -1; -- (Move Up or Move Down +1 for Up and -1 For Down)
DECLARE #SEQUENCE_NO INT = 0;
INSERT INTO #TempTable
SELECT SEQUENCE_NO ,ID
FROM TABLE_NAME S
WHERE ID = #Id
SET #SEQUENCE_NO = (SELECT SEQUENCE_NO FROM #TempTable)
INSERT INTO #TempTable
SELECT SEQUENCE_NO AS SNO,ID
FROM TABLE_NAME S
WHERE ID <> #Id
AND SEQUENCE_NO = (#SEQUENCE_NO + #NewPosition) -- (Move Up or Move Down +1 for Up and -1 For Down)
--Add check point here temp table to have 2 exact records
;WITH x AS (SELECT ID, SEQUENCE_NO FROM #TempTable WHERE ROW_ID = 1)
, y AS (SELECT ID, SEQUENCE_NO FROM #TempTable WHERE ROW_ID = 2)
UPDATE #TempTable
SET SEQUENCE_NO = z.SEQUENCE_NO
FROM (
SELECT x.ID, y.SEQUENCE_NO FROM x,y
UNION ALL
SELECT y.ID, x.SEQUENCE_NO FROM x,y
) z
WHERE #TempTable.ID = z.ID;
UPDATE SI
SET SI.SEQUENCE_NO = T.SEQUENCE_NO -- (Swap Values here)
FROM TABLE_NAME SI
JOIN #TempTable T ON SI.ID = T.ID