SQL While Exists Gets stuck in loop? - sql-server

I have a cursor that is basically inserting new usernames in a table. I am trying to check for existing ones and append a '_1' or '_2' etc.
However it appears as though my code is getting stuck in a loop and never finishes.
Here is the code in question I belive:
SET #NUM = 1
--If Username already exists append number
While Exists ( select Null from CUSTOMTABLE Where USER_PRINCIPAL_NAME = #UPN)
BEGIN
SET #UPN = #UPN+'_'+RTRIM(CONVERT(varchar(10), #NUM))
SET #NUM = #NUM+1
END
I then go on to insert the value '#upn' into a table. Am I not doing this while exists correctly?

This should absolutely work. You aren't taking NULL into account and you also are adding # repeatedly, so your string will start looking like x#, x_##, x###, etc.
SET #NUM = 1
SET #UPN=ISNULL(#UPN,'')
DECLARE #OrgUPN NVARCHAR(2000)
SET #OrgUPN = #UPN
--If Username already exists append number
While Exists ( select Null from CUSTOMTABLE Where USER_PRINCIPAL_NAME = #UPN)
BEGIN
SET #UPN = #OrgUPN+'_'+RTRIM(CONVERT(varchar(10), #NUM))
SET #NUM = #NUM+1
END

Related

SQL Server trigger Insert/Update specific column

Point is to make a trigger which will:
Check the configuration table which contains a column ConnectionField nvarchar(50)
It should return the string value (columnName) which will be used as a key
So on insert/update on table Workers, the code should set my Xfield value to the value from column ConnectionField, read from the Configuration table.
In short since this is all messy. I want to be able to let my end user to write down in configuration which column he will use as unique (Worker ID, SNSID, Name etc... ) based on his pick trigger need to put that field value to my Xfield
Don't ask why. It's really confusing.
I've written a trigger which will do that but it just is stuck somewhere in an infinite loop
CREATE TRIGGER [dbo].Tr_ConnectionField
ON [dbo].Workers
FOR INSERT, UPDATE
AS
SET NOCOUNT ON;
DECLARE #ID BIGINT
DECLARE #tmpUpit CURSOR;
DECLARE #ConFieldSETUP NVARCHAR(50)
-- Here I will read the field from configuration which will be used as key
SET #ConFieldSETUP = (SELECT TOP 1 ISNULL(ConnectionField, 'SNSID')
FROM ConfigurationTable)
BEGIN
SET #tmpUpit = CURSOR LOCAL SCROLL FOR
SELECT i.id FROM inserted i
OPEN #tmpUpit
END
FETCH NEXT FROM #tmpUpit INTO #ID
WHILE ##fetch_status = 0
BEGIN
-- Here I will use the configuration columns value to my Xfield
UPDATE Workers
SET Xfield = (SELECT #ConFieldSETUP
FROM Workers cld
WHERE cld.Id = #ID)
WHERE Id = #ID
END
FETCH NEXT FROM #tmpUpit INTO #ID
DEALLOCATE #tmpUpit
Try
CREATE TRIGGER [dbo].Tr_ConnectionField ON [dbo].Textt
FOR INSERT, UPDATE AS
SET NOCOUNT ON;
DECLARE #ConFieldSETUP nvarchar(50);
-- Stop recursion for the trigger
IF TRIGGER_NESTLEVEL(OBJECT_ID('dbo.Tr_ConnectionField')) > 1
RETURN;
-- Here i will read the field from configuration which will be used as key
SET #ConFieldSETUP = (SELECT TOP 1 ISNULL(ConnectionField, 'SNSID')
FROM ConfigurationTable
-- ORDER BY ...
);
-- Update Xfield depending on configuration
UPDATE w
SET Xfield = CASE #ConFieldSETUP
WHEN 'SNSID' THEN w.SNSID
WHEN 'Name' THEN w.Name
...
END
FROM Workers w
JOIN inserted i ON i.Id = w.Id;

Check if one of many temporary table exists and have values in SQL Server 2014

i have a stored procedure where i insert results of many controls in temporary table, at the end i have to check if all table exists and if are empty or not
i start with
IF(NOT EXISTS (SELECT TOP 1 1 FROM #tblControllo1)
AND NOT EXISTS (SELECT TOP 1 1 FROM #tblControllo2)
AND NOT EXISTS (SELECT TOP 1 1 FROM #tblControllo3)
AND NOT EXISTS (SELECT TOP 1 1 FROM #tblControllo4)
...
but i get error when some table does not exists so i have to mix those chek with
OBJECT_ID('tempdb..#tblControllo1') IS NOT NULL
but i don't find an elegant way to do it other than
DECLARE #controllo BIT = 1
IF OBJECT_ID('tempdb..#tblControllo1') IS NOT NULL
IF(EXISTS (SELECT TOP 1 1 FROM #tblControllo1) )
SET #controllo = 0
IF OBJECT_ID('tempdb..#tblControllo2') IS NOT NULL
IF(EXISTS (SELECT TOP 1 1 FROM #tblControllo2) )
SET #controllo = 0
IF OBJECT_ID('tempdb..#tblControllo3') IS NOT NULL
IF(EXISTS (SELECT TOP 1 1 FROM #tblControllo3) )
SET #controllo = 0
....
IF(#controllo = 1)
-- do stuff
is there a better way to do it?
The biggest problem is that you can't execute directly an SQL with SELECT of a table that may not exist because it will throw an error when trying to execute it. The following script uses a Dynamic SQL with a cursor to validate each table you need, breaking at the first failed condition.
DECLARE #AtLeastOneValidationFails BIT = 0
DECLARE TemporaryTableCursor CURSOR FOR
SELECT
G.TemporaryTableName
FROM
(VALUES
('#FirstTable'), -- Your tables to validate here
('#SecondTable'))
AS G (TemporaryTableName)
DECLARE #TemporaryTableName VARCHAR(100)
OPEN TemporaryTableCursor
FETCH NEXT FROM TemporaryTableCursor INTO #TemporaryTableName
WHILE ##FETCH_STATUS = 0
BEGIN
IF OBJECT_ID('tempdb..' + #TemporaryTableName) IS NULL
BEGIN
SET #AtLeastOneValidationFails = 1
BREAK
END
DECLARE #DynamicSQL NVARCHAR(MAX) = N'
IF NOT EXISTS (SELECT 1 FROM ' + #TemporaryTableName + ')
SET #ExistFails = 1'
EXEC sp_executesql
#stmt = #DynamicSQL,
#params = N'#ExistFails BIT OUTPUT',
#ExistFails = #AtLeastOneValidationFails OUTPUT
IF #AtLeastOneValidationFails = 1
BREAK
FETCH NEXT FROM TemporaryTableCursor INTO #TemporaryTableName
END
CLOSE TemporaryTableCursor
DEALLOCATE TemporaryTableCursor
SELECT
AtLeastOneValidationFails = #AtLeastOneValidationFails
This will ensure that the tables exists before issuing the SELECT (thus not failing). Please be careful with table names as this is executing Dynamic SQL.
You can wrap this in a procedure and pass the table names as parameter so you don't repeat it everywhere. You can also edit it to return the failed table name so you can debug it properly.
PD: You can omit the TOP N when doing an EXISTS as the engine is smart enough to just check if the resulting query has at least 1 row.

SQL - concatenation and iteration

Wanted to know if there is a way of iterating and concatenating a string in SQL to a new column every cycle in a while loop.
set nocount on
declare #rowcount INT,
#BL_A VARCHAR(MAX)
set #rowcount =2
while #rowcount <=12
begin
set #BL_A = '[DB1].[dbo].[Table1].[Col_'+CAST(#rowcount as varchar(MAX))+']'
print #BL_A
update [DB1].[dbo].[Table1]
set #BL_A = [DB2].[dbo].[Table2].[Y_Value]
from [DB2].[dbo].[Table2]
where [DB1].[dbo].[Table1].[X_Value] = [DB2].[dbo].[Table2].[X_Value];
set #rowcount= #rowcount+1
end
print 'End of Script'
The query runs without errors and prints off this, but doesn't update the columns
[DB1].[dbo].[Table1].[Col_2]
[DB1].[dbo].[Table1].[Col_3]
....
[DB1].[dbo].[Table1].[Col_12]
End of Script
Please create the dynamic query to update the table, try like below:
exec ('update [DB1].[dbo].[Table1]
set '+#BL_A+' = [DB2].[dbo].[Table2].[Y_Value]
from [DB2].[dbo].[Table2]
where [DB1].[dbo].[Table1].[X_Value] = [DB2].[dbo].[Table2].[X_Value];')
HTH!

Setting output parameters in SELECT statement with an IF EXISTS check

I am trying to make an efficient SQL stored procedure for retrieving user data from my database, but I am running into a syntax issue I can't seem to figure out.
Basically, I want to assign my output variable within my SELECT statement. I also want to see if the user actually exists by IF EXISTS. Unfortunately, I can't seem to do both.
Here is my procedure:
CREATE PROCEDURE [dbo].FindUser(#UserID binary(16), #UserExists bit OUTPUT, #Name
nvarchar(MAX) OUTPUT)
AS
SET NOCOUNT ON
IF EXISTS (SELECT #Name = Name FROM Users WHERE UserID = #UserID)
BEGIN
SET #UserExists = 1
END
RETURN
Currently, it gives me an "SQL46010 :: Incorrect syntax near #Name." error.
If I remove IF EXISTS, the statement compiles fine!
Why does the IF EXISTS check cause a syntax error?
set #UserExists = 0;
select #Name = Name,
#UserExists = 1
from Users
where UserID = #UserID;
SET NOCOUNT ON
IF EXISTS (SELECT 1 FROM Users WHERE UserID = #UserID)
BEGIN
SET #UserExists = 1
/* do other stuff here select user name or whatever */
END
If there is a record for #UserID in users table Selecting 1 will return true for exists clause and control will enter the BEGIN..END block.

Problems with SQL EXISTS

I'm going mad on this one. I have the following SP:
ALTER PROCEDURE [BankImport].[spBI_getIsBatchUnique]
#batchName varchar = 500
AS
BEGIN
SET NOCOUNT ON;
IF (EXISTS (SELECT 1 FROM [ACN_Main].[BankImport].[tblBI_Jobs]
WHERE [batchNumber] = #batchName))
BEGIN
SELECT 1
END
ELSE
BEGIN
SELECT 0
END
END
GO
But whatever the request is, I always get back 0!
I tried to modify it in several ways but with no success!
What I need to do is check if there is a record with that batch number and return true, otherwise return false.
Any tip?
Thanks
Your input parameter looks a bit funny
#batchName varchar = 500
Should it have been this?
#batchName varchar(500)
Ie set the length of the varchar datatype, how you currently have it, 500 is the default value for the batchName param.
I think because you compare batchNumber and batchName, try
EXISTS (SELECT 1 FROM [ACN_Main].[BankImport].[tblBI_Jobs]
WHERE [batchName] = #batchName)

Resources