Update but only what is different (what've changed) - sql-server

I've tried something like this:
UPDATE Person
SET Name = #Name, Phone = #Phone, Email = #Email, Status = #Status
WHERE Id = #Id AND Name != #Name AND Phone != #Phone AND Email != #Email AND Status != #Status;
But isn't working.

If Id is your primary key then you probably want:
UPDATE Person
SET Name = #Name, Phone = #Phone, Email = #Email, Status = #Status
WHERE Id = #Id AND
(Name != #Name OR Phone != #Phone OR Email != #Email OR Status != #Status);
But there generally isn't any harm in updating columns to the same value unless you have some sort of trigger that you don't want to run. Even with the code above, if only one of the column values changes, you're going to "update" the other three to their same value.

Here is another way to prevent unnecessary updates.
It is using set based operator INTERSECT, and it won't trip on NULL values in comparison:
AND (Name != #Name OR Phone != #Phone OR Email != #Email)
The solution is using UpdatedOn DATETIMEOFFSET(3) column to track the updated DateTime.
SQL
-- DDL and sample data population, start
DECLARE #person TABLE (
ID INT PRIMARY KEY,
Name VARCHAR(20),
Phone VARCHAR(15),
Email VARCHAR(128),
UpdatedOn DATETIMEOFFSET(3)
);
INSERT #person (ID, Name, Phone, Email, UpdatedOn) VALUES
(1, 'Peter', '1-305-803-1234', 'peter#gmail.com', NULL),
(2, 'Paul', NULL, 'paul#gmail.com', NULL);
-- DDL and sample data population, end
-- before
SELECT * FROM #person;
DECLARE #ID INT = 1
, #Name VARCHAR(20) = 'Peter' -- try 'PeterZ'
, #Phone VARCHAR(15) = '1-305-803-1234'
, #Email VARCHAR(128) = 'peter#gmail.com';
;WITH rs AS
(
SELECT #ID AS ID
, #Name AS NAme
, #Phone AS Phone
, #Email AS Email
)
UPDATE T
SET Name = S.Name, Phone = S.Phone, Email = S.Email
, T.UpdatedOn = SYSDATETIMEOFFSET()
FROM #person AS T -- target
INNER JOIN rs AS S -- source
ON T.ID = S.ID
WHERE NOT EXISTS (SELECT S.*
INTERSECT SELECT T.ID, T.Name, T.Phone, T.Email);
-- test
SELECT * FROM #person;

Related

How to insert data into a temporary table using an existing table and new columns

I am trying to insert data into a temporary table within my stored procedure. The data is selected from an existing table and creating new columns with concatenated data. I'm getting an error that the column name or number of supplied values does not match table definition. I'm pretty certain that the code in my application is correct so I believe the issue is with the way I'm storing the data in a temporary table.
Here is my proc:
AS
BEGIN
CREATE TABLE #TempTable
(
[ID] [varchar](10),
[FIRST_NAME] varchar(50),
[LAST_NAME] varchar(50),
[WEBSITE_LINK] varchar(200)
)
INSERT INTO #TempTable
SELECT USER.ID,USER.FIRSTNAME AS [FIRST_NAME], USER.LASTNAME AS
[LAST_NAME]
FROM USER
WHERE USER.Registered = 'Yes'
DECLARE #Link1 NVARCHAR(100)
DECLARE #Link2 VARCHAR(10)
DECLARE #Link3 NVARCHAR(4)
SET #Link1 = 'http://www.mywebsite.com/user/'
SET #Link2 = (SELECT USER.ID FROM USER WHERE USER.Registered =
'Yes')
SET #Link3 ='/document.doc'
SET #WEBSITE_LINK = (SELECT concat(#Link1,#Link2,#Link3 )AS
[WEBSITE_LINK])
DROP TABLE #TempTable
END
I think this is your problem:
SET #Link2 = (SELECT USER.ID FROM USER WHERE USER.Registered = 'Yes')
What if there are six of them? A single variable can't hold all of them. You can do:
SELECT TOP(1) #Link2 = USER.ID FROM USER WHERE USER.Registered = 'Yes' ORDER BY [SOMETHING];
If the goal is to create a temp table with a full [WEBSITE_LINK], you can do that without all those variables:
BEGIN
CREATE TABLE #TempTable
(
[ID] [varchar](10),
[FIRST_NAME] varchar(50),
[LAST_NAME] varchar(50),
[WEBSITE_LINK] varchar(200)
)
INSERT INTO #TempTable
SELECT DISTINCT u.ID
, [FIRST_NAME] = u.FIRSTNAME
, [LAST_NAME] = u.LASTNAME
, [WEBSITE_LINK] = 'http://www.mywebsite.com/user/' +
CAST(u.ID AS VARCHAR(10)) +
'/document.doc'
FROM [USER] u
WHERE u.Registered = 'Yes'
-- Do something with these values...
DROP TABLE #TempTable
END

SQL Server cursor - cannot assign variable properly [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
I use SQL Server 2016. I need to move users from a legacy system to a new one. But before bringing all users from the legacy system, I need to check if they do not already exist in our new system. Such a determination is done based on comparison of users' email addresses in each of the system.
So if a user does not exist in the new system, I need to insert such a record into the new system from the legacy one. But if user does exist, I need to update some columns in the new system with data from the legacy one.
To accomplish it I'm using a cursor with SCOPE_IDENTITY().
Also I need to log newly inserted and existing updated records in each cursor iteration. The problem is that my code does not differentiate new and existing records hence it inserts all user id in the Log table twice. One time in case the userID (#ContactID) IS NULL (not existing in the new system) and another when userID (#ContactID) IS NOT NULL - existing in the new system.
In my sample below I have 1 records that does not exists in the new system and 3 do match already. So in the IF (#CoantactID IS NULL) I meant to insert only that newly inserted into the MyDB.dbo.Contact table record and in the IF (#CoantactID IS NOT NULL) insert into the Log table only the tree records matched (existing) in the new system.
But the problem is that it inserts all four ContactIDs into the log table even in the this IF (#ContactID IS NULL) amd then again for in IF (#ContactID IS NOT NULL)
;USE [MyDB];
GO
-- exec dbo.sp_UserMigration_Users_Copy
DROP PROCEDURE IF EXISTS dbo.sp_UserMigration_Users_Copy
GO
;USE [MyDB];
GO
CREATE PROCEDURE dbo.sp_UserMigration_Users_Copy
#UserID UNIQUEIDENTIFIER = NULL
--,#ContactID INT
AS
DECLARE #Email nvarchar(100),
#ContactID INT;
-- #UserID UNIQUEIDENTIFIER,
DECLARE #SysID INT
SET #SysId = 17511; -- system contactID
---- creating log table
--CREATE TABLE #T
--(
-- UserID UNIQUEIDENTIFIER NOT NULL,
-- Email NVARCHAR(50) NOT NULL
--);
SELECT * INTO #T
FROM MyDB.dbo.User
WHERE UserID IN (
'0604C514',
'C1FDAF34',
'23BABE2D',
'EBA21D10'
);
IF NOT EXISTS (select * from MyDB.sys.tables where name = N'UserIDContactIDMigrationLog')
CREATE TABLE MyDB.dbo.UserIDContactIDMigrationLog
(
UserID UNIQUEIDENTIFIER /* CONSTRAINT [PK_UserIDContactIDMigrationLog_UserID] PRIMARY KEY */ NOT NULL, -- somehow inserts duplicate UserIDs
ContactId INT /*UNIQUE CONSTRAINT [UNIQUE_ContactId] */ NOT NULL,
CreatedDt DATETIME2 NULL,
UpdatedDt DATETIME2 NULL,
UpdatedFlag BIT /*CONSTRAINT [DF_MigratedFlag] DEFAULT(0) */ NULL
);
-- -----------------------------------------------------
-- Cursor: For all contacts to be migrated
-- -----------------------------------------------------
IF (SELECT CURSOR_STATUS('global','user_cursor')) >= -1
BEGIN
IF (SELECT CURSOR_STATUS('global','user_cursor')) > -1
BEGIN
CLOSE user_cursor
END
DEALLOCATE user_cursor
END
DECLARE user_cursor CURSOR
FOR
SELECT a.UserID, LTRIM(RTRIM(a.Email)) AS Email
FROM #T a WITH (NOLOCK)
--WHERE a.UserID = #UserID
-- begin cursor loop
OPEN user_cursor
FETCH NEXT FROM user_cursor INTO #UserID, #Email
WHILE ##FETCH_STATUS = 0
BEGIN
SELECT #ContactID = (
SELECT c.ContactId
FROM MyDB.dbo.Contact c
LEFT OUTER JOIN MyDB.dbo.Login l ON c.ContactId = l.ContactId
WHERE (LTRIM(RTRIM(c.ContactEmailTx)) = #Email
OR LTRIM(RTRIM(l.ContactLoginNameTx)) = #Email
--OR l.ContactLoginNameTx LIKE #Email+'%' -- this concept does not work in case of leading space at the ContactLoginNameTx so need to use the code below
OR SUBSTRING(LTRIM(RTRIM(l.ContactLoginNameTx)), -1, CHARINDEX('.INACTIVE.', l.ContactLoginNameTx)) = #Email)
AND (c.ContactEmailTx != '' OR c.ContactEmailTx IS NOT NULL OR l.ContactLoginNameTx != '' OR l.ContactLoginNameTx IS NOT NULL)
)
-- check if a contact is new
IF (#ContactID IS NULL)
BEGIN
-- -----------------------------------------------------
-- MyDB.dbo.Contact
-- -----------------------------------------------------
INSERT INTO [MyDB].[dbo].[Contact]
(
[ContactFirstNameTx],
[ContactLastNameTx],
[ContactEmailTx],
[ContactTitleTx],
[ContactCreateDt],
[ContactCreateByID],
[ContactCreateLoginTypeID]
)
SELECT
[FirstName],
[LastName],
[Email],
[Title],
--[AccountId],
[UserCreatedDate],
#SysId AS [ContactCreateByID], -- as as flag for import [ContactCreateLoginTypeID]
-10 AS [ContactCreateLoginTypeID]
FROM #T o WITH (NOLOCK)
WHERE UserID = #UserID
SET #ContactID = SCOPE_IDENTITY()
END
-- select * from [MyDB].[dbo].[Contact] where contactid in ( 1051364, 466440, 560466, 618576)
-- -----------------------------------------------------
--MyDB.dbo.Login
-- -----------------------------------------------------
INSERT INTO [MyDB].[dbo].[Login]
(
ContactID,
[ContactLoginNameTx], -- V.C. this is email. the field is has a unique constraint
[ContactLoginActiveIn],
[ContactLoginCreateDt],
[ContactLoginCreateByID],
[ContactLoginCreateLoginTypeID],
[ContactLoginPasswordLastChangeDt],
[ContactLoginLastLoginDt],
[ContactLoginPasswordExclusionIn] -- this is not nullable and BIT
)
SELECT
#ContactID AS ContactID,
[Email],
CASE WHEN [UserStatusID] IN (1, 3) THEN 1 ELSE 0 END AS [ContactLoginActiveIn], -- v.c. in Onvia 1 is Active, 2 - Inactive, 3 - Invited, 4 - Inactive By System, 5 - Pending Registration
[UserCreatedDate],
#SysId AS ContactLoginCreateByID, -- as as flag for Onvia import[ContactCreateLoginTypeID]
-10 AS [ContactLoginCreateLoginTypeID],
[UserLastPasswordChangedDate],
[UserLastLoginDate],
0 as ContactLoginPasswordExclusionIn -- this is not nullable and BIT
FROM #T o WITH (NOLOCK)
WHERE UserID = #UserID
AND NOT EXISTS (select * from MyDB.dbo.Login z where z.ContactID = #ContactID)
-- -----------------------------------------------------
-- Activate any inactive users
-- -----------------------------------------------------
IF EXISTS (select * from MyDB.dbo.Login where ContactLoginActiveIn = 0 and ContactID = #ContactID)
AND NOT EXISTS (select * from MyDB.dbo.Login where ContactLoginActiveIn = 1 and ContactID = #ContactID)
BEGIN
UPDATE [MyDB].[dbo].[Login]
SET ContactLoginNameTx = #Email,
ContactLoginActiveIn = (select case when [UserStatusID] IN (1, 3) then 1 else 0 end
from #T o where o.UserID = #UserID)
WHERE ContactID = #ContactID
END
-- -----------------------------------------------------
--MyDB.dbo.ContactPhoneNumber
-- -----------------------------------------------------
INSERT INTO [MyDB].[dbo].[PhoneNumber]
(
ContactID,
PhoneNumberTypeID,
ContactPhoneNumberValueTx
)
SELECT
#ContactID AS ContactID,
1 AS PhoneNumberTypeID,
ISNULL([PhoneNumber1],'') AS ContactPhoneNumberValueTx
FROM #T o WITH (NOLOCK)
WHERE o.UserID = #UserID
AND NOT EXISTS (select * from [MyDB].[dbo].[PhoneNumber] z where z.ContactID = #ContactID);
-- -----------------------------------------------------
--MyDB.dbo.ContactOrg
-- -----------------------------------------------------
INSERT INTO [MyDB].[dbo].[Org]
(
ContactID,
OrgID
)
SELECT
#ContactID AS ContactID,
b.OrgID AS OrgID
FROM #T o WITH (NOLOCK)
INNER JOIN ImportQueue.dbo.OnviaAccountIDOrgIDMigrationLog b WITH (NOLOCK) ON o.AccountId = b.OnviaAccountID
WHERE o.UserID = #UserID
AND NOT EXISTS (select * from [MyDB].[dbo].[Org] z where z.ContactID = #ContactID);
-- -----------------------------------------------------
---- MyDB.dbo.UserIDContactIDMigrationLog
---- log output for new users
-- -----------------------------------------------------
INSERT INTO MyDB.dbo.UserIDContactIDMigrationLog
(
UserID,
ContactId,
CreatedDt,
UpdatedFlag
)
VALUES
(
#UserID,
#ContactID,
GETDATE(),
0
)
-- -----------------------------------------------------
-- EXISTING MATCHED USERS
-- -----------------------------------------------------
-- check if a contact is existing
IF (#ContactID IS NOT NULL)
BEGIN
-- -----------------------------------------------------
-- MyDB.dbo.Contact
-- -----------------------------------------------------
UPDATE MyDB.dbo.Contact
SET ContactFirstNameTx =
CASE
WHEN ContactFirstNameTx NOT IN ('', NULL) THEN c.FirstName
ELSE ContactFirstNameTx
END,
ContactLastNameTx =
CASE
WHEN ContactLastNameTx IN ('', NULL) THEN c.LastName
ELSE ContactLastNameTx
END,
ContactEmailTx =
CASE
WHEN ContactEmailTx IN ('', NULL) THEN c.Email
ELSE ContactEmailTx
END,
ContactTitleTx =
CASE
WHEN ContactTitleTx IN ('', NULL) THEN c.Title
ELSE ContactTitleTx
END,
[ContactCreateDt] =
CASE
WHEN ContactCreateDt IN ('', NULL) THEN c.UserCreatedDate
ELSE ContactCreateDt
END,
[ContactModifyByID] = #SysId,
[ContactModifyLoginTypeID] = - 10
FROM #T c
WHERE UserID = #UserID
AND ContactID = #ContactID;
-- -----------------------------------------------------
---- MyDB.dbo.UserIDContactIDMigrationLog
---- log output for existing matched users
-- -----------------------------------------------------
INSERT INTO MyDB.dbo.UserIDContactIDMigrationLog
(
UserID,
ContactId,
UpdatedDt,
UpdatedFlag
)
VALUES
(
#UserID,
#ContactID,
GETDATE(),
1
);
FETCH NEXT FROM user_cursor INTO #UserID, #Email
-- end cursor loop
END
END
CLOSE user_cursor
DEALLOCATE user_cursor
GO
Instead of Cursors try the below code.
- exec dbo.sp_UserMigration_Users_Copy
DROP PROCEDURE IF EXISTS dbo.sp_UserMigration_Users_Copy
GO
;USE [MyDB];
GO
CREATE PROCEDURE dbo.sp_UserMigration_Users_Copy
#UserID UNIQUEIDENTIFIER = NULL
--,#ContactID INT
AS
DECLARE #Email nvarchar(100),
#ContactID INT;
DECLARE #SysID INT
SET #SysId = 17511;
CREATE TABLE #T
(
ID INT IDENTITY(1,1) NOT NULL,
UserID NVARCHAR(50)NOT NULL,
Email NVARCHAR(50) NOT NULL
);
INSERT INTO #T
SELECT *
FROM MyDB.dbo.User
WHERE UserID IN (
'0604C514',
'C1FDAF34',
'23BABE2D',
'EBA21D10'
);
IF NOT EXISTS (select * from MyDB.sys.tables where name = N'UserIDContactIDMigrationLog')
CREATE TABLE MyDB.dbo.UserIDContactIDMigrationLog
(
UserID UNIQUEIDENTIFIER /* CONSTRAINT [PK_UserIDContactIDMigrationLog_UserID] PRIMARY KEY */ NOT NULL, -- somehow inserts duplicate UserIDs
ContactId INT /*UNIQUE CONSTRAINT [UNIQUE_ContactId] */ NOT NULL,
CreatedDt DATETIME2 NULL,
UpdatedDt DATETIME2 NULL,
UpdatedFlag BIT /*CONSTRAINT [DF_MigratedFlag] DEFAULT(0) */ NULL
);
DECLARE #COUNT INT
DECLARE #I INT = 1
DECLARE #UserID NVARCHAR(50) ;
DECLARE #Email NVARCHAR(50)
SELECT #COUNT = COUNT(*) FROM #T
WHILE(#I <= #COUNT)
BEGIN
SELECT #UserID = UserID, #Email= LTRIM(RTRIM(Email)) FROM #T WHERE ID = #I
SELECT #ContactID = (
SELECT c.ContactId
FROM MyDB.dbo.Contact c
LEFT OUTER JOIN MyDB.dbo.Login l ON c.ContactId = l.ContactId
WHERE (LTRIM(RTRIM(c.ContactEmailTx)) = #Email
OR LTRIM(RTRIM(l.ContactLoginNameTx)) = #Email
--OR l.ContactLoginNameTx LIKE #Email+'%' -- this concept does not work in case of leading space at the ContactLoginNameTx so need to use the code below
OR SUBSTRING(LTRIM(RTRIM(l.ContactLoginNameTx)), -1, CHARINDEX('.INACTIVE.', l.ContactLoginNameTx)) = #Email)
AND (c.ContactEmailTx != '' OR c.ContactEmailTx IS NOT NULL OR l.ContactLoginNameTx != '' OR l.ContactLoginNameTx IS NOT NULL)
)
-- check if a contact is new
IF (#ContactID IS NULL)
BEGIN
-- -----------------------------------------------------
-- MyDB.dbo.Contact
-- -----------------------------------------------------
INSERT INTO [MyDB].[dbo].[Contact]
(
[ContactFirstNameTx],
[ContactLastNameTx],
[ContactEmailTx],
[ContactTitleTx],
[ContactCreateDt],
[ContactCreateByID],
[ContactCreateLoginTypeID]
)
SELECT
[FirstName],
[LastName],
[Email],
[Title],
--[AccountId],
[UserCreatedDate],
#SysId AS [ContactCreateByID], -- as as flag for Onvia import[ContactCreateLoginTypeID]
-10 AS [ContactCreateLoginTypeID]
FROM #T o WITH (NOLOCK)
WHERE UserID = #UserID
SET #ContactID = SCOPE_IDENTITY()
END
-- select * from [MyDB].[dbo].[Contact] where contactid in ( 1051364, 466440, 560466, 618576)
-- -----------------------------------------------------
--MyDB.dbo.Login
-- -----------------------------------------------------
INSERT INTO [MyDB].[dbo].[Login]
(
ContactID,
[ContactLoginNameTx], -- V.C. this is email. the field is has a unique constraint
[ContactLoginActiveIn],
[ContactLoginCreateDt],
[ContactLoginCreateByID],
[ContactLoginCreateLoginTypeID],
[ContactLoginPasswordLastChangeDt],
[ContactLoginLastLoginDt],
[ContactLoginPasswordExclusionIn] -- this is not nullable and BIT
)
SELECT
#ContactID AS ContactID,
[Email],
CASE WHEN [UserStatusID] IN (1, 3) THEN 1 ELSE 0 END AS [ContactLoginActiveIn], -- v.c. in Onvia 1 is Active, 2 - Inactive, 3 - Invited, 4 - Inactive By System, 5 - Pending Registration
[UserCreatedDate],
#SysId AS ContactLoginCreateByID, -- as as flag for Onvia import[ContactCreateLoginTypeID]
-10 AS [ContactLoginCreateLoginTypeID],
[UserLastPasswordChangedDate],
[UserLastLoginDate],
0 as ContactLoginPasswordExclusionIn -- this is not nullable and BIT
FROM #T o WITH (NOLOCK)
WHERE UserID = #UserID
AND NOT EXISTS (select * from MyDB.dbo.Login z where z.ContactID = #ContactID)
-- -----------------------------------------------------
-- Activate any inactive users
-- -----------------------------------------------------
IF EXISTS (select * from MyDB.dbo.Login where ContactLoginActiveIn = 0 and ContactID = #ContactID)
AND NOT EXISTS (select * from MyDB.dbo.Login where ContactLoginActiveIn = 1 and ContactID = #ContactID)
BEGIN
UPDATE [MyDB].[dbo].[Login]
SET ContactLoginNameTx = #Email,
ContactLoginActiveIn = (select case when [UserStatusID] IN (1, 3) then 1 else 0 end
from #T o where o.UserID = #UserID)
WHERE ContactID = #ContactID
END
-- -----------------------------------------------------
--MyDB.dbo.ContactPhoneNumber
-- -----------------------------------------------------
INSERT INTO [MyDB].[dbo].[PhoneNumber]
(
ContactID,
PhoneNumberTypeID,
ContactPhoneNumberValueTx
)
SELECT
#ContactID AS ContactID,
1 AS PhoneNumberTypeID,
ISNULL([PhoneNumber1],'') AS ContactPhoneNumberValueTx
FROM #T o WITH (NOLOCK)
WHERE o.UserID = #UserID
AND NOT EXISTS (select * from [MyDB].[dbo].[PhoneNumber] z where z.ContactID = #ContactID);
-- -----------------------------------------------------
--MyDB.dbo.ContactOrg
-- -----------------------------------------------------
INSERT INTO [MyDB].[dbo].[Org]
(
ContactID,
OrgID
)
SELECT
#ContactID AS ContactID,
b.OrgID AS OrgID
FROM #T o WITH (NOLOCK)
INNER JOIN ImportQueue.dbo.OnviaAccountIDOrgIDMigrationLog b WITH (NOLOCK) ON o.AccountId = b.OnviaAccountID
WHERE o.UserID = #UserID
AND NOT EXISTS (select * from [MyDB].[dbo].[Org] z where z.ContactID = #ContactID);
-- -----------------------------------------------------
---- MyDB.dbo.UserIDContactIDMigrationLog
---- log output for new users
-- -----------------------------------------------------
INSERT INTO MyDB.dbo.UserIDContactIDMigrationLog
(
UserID,
ContactId,
CreatedDt,
UpdatedFlag
)
VALUES
(
#UserID,
#ContactID,
GETDATE(),
0
)
-- -----------------------------------------------------
-- EXISTING MATCHED USERS
-- -----------------------------------------------------
-- check if a contact is existing
IF (#ContactID IS NOT NULL)
BEGIN
-- -----------------------------------------------------
-- MyDB.dbo.Contact
-- -----------------------------------------------------
UPDATE MyDB.dbo.Contact
SET ContactFirstNameTx =
CASE
WHEN ContactFirstNameTx NOT IN ('', NULL) THEN c.FirstName
ELSE ContactFirstNameTx
END,
ContactLastNameTx =
CASE
WHEN ContactLastNameTx IN ('', NULL) THEN c.LastName
ELSE ContactLastNameTx
END,
ContactEmailTx =
CASE
WHEN ContactEmailTx IN ('', NULL) THEN c.Email
ELSE ContactEmailTx
END,
ContactTitleTx =
CASE
WHEN ContactTitleTx IN ('', NULL) THEN c.Title
ELSE ContactTitleTx
END,
[ContactCreateDt] =
CASE
WHEN ContactCreateDt IN ('', NULL) THEN c.UserCreatedDate
ELSE ContactCreateDt
END,
[ContactModifyByID] = #SysId,
[ContactModifyLoginTypeID] = - 10
FROM #T c
WHERE UserID = #UserID
AND ContactID = #ContactID;
-- -----------------------------------------------------
---- MyDB.dbo.UserIDContactIDMigrationLog
---- log output for existing matched users
-- -----------------------------------------------------
INSERT INTO MyDB.dbo.UserIDContactIDMigrationLog
(
UserID,
ContactId,
UpdatedDt,
UpdatedFlag
)
VALUES
(
#UserID,
#ContactID,
GETDATE(),
1
);
END
SET #I = #I+1;
END

Merge into table with parameter

I'm stuck and i know that this is easier than i think it is.
I have a table that looks like this:
SELECT ID , NAME , CITY FROM TEMP
I have created a Merge statement with Parameters that should insert a new row if ID and City does not already exist
ALTER PROCEDURE [dbo].[sp_TMP]
#ID INT,
#City NVARCHAR(50)
AS
MERGE TEMP AS TARGET
USING
(
SELECT
ID,
NAME,
CITY
FROM TEMP
) AS SOURCE
ON [TARGET].[ID]= #ID AND [TARGET].[City] = #City
WHEN NOT MATCHED THEN
INSERT
(
[ID],
[NAME],
[CITY]
)
VALUES
(
#ID,
[SOURCE].[NAME],
#City
);
I know im doing something wrong here because ALLA the records gets effected.
I would like a outcome of this (if #ID = '1' and #City = 'New York')
I would like to use a MERGE() and not "Insert into" if possible.
First I'd like to say the consistency of a solution like this isn't good at all.
However, in order for it to work as you described in the comments, change the code like so:
ALTER PROCEDURE [dbo].[sp_TMP]
#ID INT,
#City NVARCHAR(50)
AS
MERGE TEMP AS TARGET
USING
(
SELECT
ID,
NAME,
CITY
FROM TEMP
) AS SOURCE
ON [TARGET].[ID]= #ID AND [TARGET].[City] = #City
WHEN NOT MATCHED THEN
INSERT
(
[ID],
[NAME],
[CITY]
)
VALUES
(
#ID,
(SELECT TOP(1) t.Name FROM TEMP t WHERE t.ID = #ID),
#City
);
Should do the trick.
Also, I'm not sure why you want to use MERGE only, but this would be a good candidate for IF NOT EXISTS ... INSERT INTO like so:
ALTER PROCEDURE [dbo].[sp_TMP]
#ID INT,
#City NVARCHAR(50)
AS
IF NOT EXISTS (SELECT TOP(1) 1 FROM TEMP WHERE ID = #ID AND City = #City)
INSERT INTO TEMP(ID, City, Name)
VALUES (#ID, #City, (SELECT TOP(1) Name FROM TEMP WHERE ID = #ID));
If you are using the code first approach you simply use [Index(IsUnique = true)] try this.Ex:
[Required]
[Column(TypeName = "varchar")]
[StringLength(100)]
[Index(IsUnique = true)]
public string Name { get; set; }

My stored procedure cannot show any record in application

I use this stored procedure in my application to fetch record but there is no record fetch from db using this SP.Give message that no Record found
CREATE PROCEDURE [dbo].[Proc_RptDailySummaryPTCLBillsCollection_Result]
(
#DateFrom DATETIME,
#DatTo DATETIME,
#SubOfficeID VARCHAR(200),
#GroupId INT,
#ClerkName VARCHAR(200),
#Type VARCHAR(200)
)
AS BEGIN
DECLARE #AgencyTable TABLE (
GpoId INT
, OfcId INT
, Total_Bills BIGINT
, Total_Amount BIGINT
) --Bill_Value BIGINT, Commission BIGINT,
--SET #DatTo = convert(datetime, convert(Varchar(12), #DatTo, 109) + ' 23:59:59PM')
-- Billing Summary By GPO Name
INSERT #AgencyTable (GpoId, OfcId, Total_Bills, Total_Amount) --Bill_Value, Commission,
SELECT
Bil.GroupId
, Bil.SubOfficeId
, ISNULL(COUNT(Bil.ConsumerNumber), 0) --AS Total_Bills,
-- ,ISNULL(SUM(Bil.C_Amount),0) --AS Bill_Value,
--,ISNULL(SUM(Bil.Commission),0) --AS Commission,
, ISNULL(SUM(Bil.C_Amount), 0) - ISNULL(SUM(Bil.Commission), 0) --AS Total_Amount
FROM BillTxnSO AS Bil
INNER JOIN pp_offices ofc ON Bil.GroupId = ofc.Group_Id AND Bil.SubOfficeId = ofc.OfficeCode
WHERE Bil.GroupId = #GroupId
AND TransDate BETWEEN #DateFrom AND #DatTo
GROUP BY Bil.GroupId, Bil.SubOfficeId
--select * from #AgencyTable
SELECT
ofc.OfficeName AS SubOffice
, ofc.Group_ID AS GroupID
, ISNULL(gpo.Total_Bills, 0) AS NoOfBills
, ISNULL(gpo.Total_Amount, 0) AS Amount -- isnull(gpo.Bill_Value,0)as Bill_Value , isnull(gpo.Commission,0) as Commission,
FROM #AgencyTable gpo
INNER JOIN pp_offices ofc ON ofc.Group_ID = gpo.GpoId AND gpo.OfcId = ofc.OfficeCode
ORDER BY ofc.OfficeName
END
"Give message that no record found"
Use ##ROWCOUNT
IF(##ROWCOUNT = 0)BEGIN
Select 'No record found'
return
END

Get highest value of a column in a stored procedure in SQLServer

I have the following stored procedure in SQL Server
IF OBJECT_ID ('kii.p_CreateSection') IS NOT NULL
DROP PROCEDURE kii.p_CreateSection
GO
CREATE PROCEDURE kii.p_CreateSection
#Name AS NVARCHAR(200),
#DocumentId AS INT,
#TypeId AS INT = NULL,
#ReportId AS INT = NULL,
#OrdinalPosition AS SMALLINT
AS
INSERT INTO kii.Section (Name, DocumentId, TypeId, ReportId, OrdinalPosition)
VALUES (#Name, #DocumentId, #TypeId, #ReportId, #OrdinalPosition)
SELECT SCOPE_IDENTITY();
GO
GRANT EXECUTE on kii.p_CreateSection TO p_role_kii
GO
The table Section is related to Document. Each document has several sections and they're ordered by the OrdinalPosistion value.
I'd like to test that if the given value for #OrdinalPosition is 0, then set it at the maximum value of all the sections of this Document +1.
Insert kii.Section( Name, DocumentId, TypeId, ReportId, OrdinalPosition )
Select #Name, #DocumentId, #TypeId, #ReportId
, Case
When #OrdinalPosition <> 0 Then #OrdinalPosition
Else (
Select Max( OrdinalPosition ) + 1
From kii.Section
Where DocumentId = #DocumentId
)
End

Resources