How to assign variable inside CTE - tsql

If I run below script, the print statement will print 10
declare #i int = 0
select #i = #i + 2
from sys.tables
print #i
But if I want to use the same concept inside CTE, it does not work.
I'm trying to run below T-SQL, but I get error
declare #i int = 0
;with ct (x) as
(
select #i = #i + 2
from sys.tables
)
select *
from ct
print #i
I get this error
Msg 102, Level 15, State 1, Line 4
Incorrect syntax near '='.
My intention is adding up the variable #i without while loop.

Related

Output parameter from TSQL sp_executesql seems to be null

I'm sure there's a simple explanation. I'm trying to print out the Max ID for all tables with an Identity column.
The TSQL code below seems to run fine in the sense that the Results window contains cells with values, but the Messages window does not show: Table1 Row Count = 99
Seems as if the #Result variable is NULL when it gets to the PRINT command.
Am I missing something obvious or is the OUTPUT command working differently than I expect?
DECLARE #TABLE VARCHAR(100)
DECLARE #FIELD VARCHAR(100)
DECLARE #SQL NVARCHAR(300)
DECLARE #result BIGINT
DECLARE CUR CURSOR FOR
SELECT
[table] = t.name,
[colname] = c.name
FROM sys.schemas AS s
INNER JOIN sys.tables AS t
ON s.[schema_id] = t.[schema_id]
INNER JOIN sys.identity_columns c ON c.object_id = t.[object_id]
OPEN CUR
FETCH NEXT FROM CUR INTO #TABLE, #FIELD
WHILE ##FETCH_STATUS = 0
BEGIN
SET #SQL = 'SELECT MAX([' + #FIELD + ']) FROM [' + #TABLE + ']'
EXEC sp_executesql #SQL,
N'#result int OUTPUT',
#result OUTPUT
PRINT #TABLE + ' Row Count = ' + CONVERT(nvarchar, #result)
--NOTHING SEEMS TO BE PRINTED HERE
FETCH NEXT FROM CUR INTO #TABLE, #FIELD
END
CLOSE CUR
DEALLOCATE CUR

SQL Server 2012: check if is uniqueidentifier and convert to string

I am trying to test if a variable is a uniqueidentifier and if it is then convert it to string but it fails:
Declare #Item VARCHAR(50)
Declare #OutString varchar(max) ;
--#Outstring is populated from various tables each cell separated by ','
--Getting the #Item from the #Outstring and convert it if its uid
DECLARE #Pos INT
DECLARE #Loop BIT
SELECT #Loop = CASE WHEN LEN(#OutString) > 0 THEN 1 ELSE 0 END
WHILE (SELECT #Loop) = 1
BEGIN
SELECT #Pos = CHARINDEX(',', #OutString, 1)
IF #Pos > 0
BEGIN
SELECT #Item = SUBSTRING(#OutString, 1, #Pos - 1)
SELECT #OutString = SUBSTRING(#OutString, #Pos + 1, LEN(#OutString) - #Pos)
IF (TRY_CONVERT(UNIQUEIDENTIFIER, #Item) IS NOT NULL)
BEGIN
CONVERT(NVARCHAR(50), #Item) AS #Item --ERROR LINE incorrect syntax
END
END
END
it is either
select #Item = convert(nvarchar(50), #Item)
or
select #Item = cast(#Item as nvarchar(50))
The syntax error is because you have said the action but not what SQL should do with it.
Do you want the string to be returned?
SELECT CONVERT(NVARCHAR(50), #Item) AS Item
Appended to #Item? (but this variable is inside your loop?)
SET #Item += CONVERT(NVARCHAR(50), #Item)
Not sure what you want to do once you have converted the string. Maybe you need another variable to add the string on (like above except not SET #Item)
Use
SELECT convert(nvarchar(50), #Item ) as Item

TSQL Replace Doubled Characters

Let's say I have data:
heloo
cuube
triniity
How to write script that will replace those "doubled" characters with only one? So the result from the above data set would be:
helo
cube
trinity
Usually I post some script where I tried to achieve this, but this time I can't think of any.
This should work:
CREATE PROCEDURE remove_duplicate_characters(#string VARCHAR(100))
AS
DECLARE #result VARCHAR(100)
SET #result=''
SELECT #result=#result+MIN(SUBSTRING(#string ,number,1)) FROM
(
SELECT number FROM master..spt_values WHERE type='p' AND number BETWEEN 1 AND len(#string )) AS t GROUP BY SUBSTRING(#string,number,1) ORDER BY MIN(number)
)
SELECT #result
GO
You then call it like this:
EXEC remove_duplicate_characters 'heloo'
Source
This script does not depend on having access to master functions, and just relies on t-sql string functions.
declare #word varchar(100) = 'aaaacuuuuuubeeeee', #result varchar(100) = ''
declare #letter char, #idx int = 0, #lastletter char = ''
while(#idx <= len(#word))
begin
select #letter = substring(#word,#idx,1)
if (#letter != #lastletter)
begin
select #result = concat(#result,#letter)
end
select #lastletter = #letter,#idx = #idx + 1
end
select #result

NULLIF check for empty string returns empty string with a column name, but NULL with the column value

I have a database column set to char(255) (yes, CHAR. Don't ask me why that's how the database was set up) that at present has an empty string with two spaces (i.e. " "). Using NULLIF(LTRIM(RTRIM(column_name)), '') does NOT work (the output is [two empty spaces]). However, using NULLIF(' ', '') works correctly and the output is NULL. In other words, the actual column value works correctly, while passing the name of the column returns an incorrect value.
Any ideas on this?
I believe the column must have more than just spaces. For example:
CREATE TABLE #x(id INT, y CHAR(255));
INSERT #X SELECT 1, ' '
UNION ALL SELECT 2, ' '
UNION ALL SELECT 3, ' ' + CHAR(9);
SELECT id, NULLIF(LTRIM(RTRIM(y)),'') FROM #x;
Results:
1 NULL
2 NULL
3
For a row where this fails, try this:
DECLARE #s CHAR(255);
SELECT #s = y FROM #x WHERE id = 3;
DECLARE #i INT;
SET #i = 1;
WHILE #i <= DATALENGTH(#s)
BEGIN
IF ASCII(SUBSTRING(#s, #i, 1)) <> 32
BEGIN
PRINT 'Position ' + RTRIM(#i) + ' = CHAR('
+ RTRIM(ASCII(SUBSTRING(#s, #i, 1))) + ')';
END
SET #i = #i + 1;
END
It should tell you what other characters are in there, and where.

How do I get the return value from a CASE statement as a dynamic SQL query?

DECLARE #command = 'SELECT CASE WHEN ( SELECT COUNT(*)
FROM [table] WITH ( NOLOCK )
WHERE DATEDIFF(minute, systemupdatedtimestamp, GETDATE()) < 10
) > 0 THEN 0
ELSE 1
END'
Now I need to get the 'return value' of the above command (0 or 1).
EXEC(#commnad)
How do I get the return value from the above?
I tried
SET #ReturnValue = EXEC(#command)
but no luck.
use sp_executesql
in your case it is something like:
declare #myOut bit
declare #SQLString nvarchar(500)
set #SQLString = N'SELECT #myOutValue = CASE WHEN ( SELECT COUNT(*)
FROM [table] WITH ( NOLOCK )
WHERE DATEDIFF(minute, systemupdatedtimestamp, GETDATE()) < 10
) > 0 THEN 0
ELSE 1
END'
declare #ParmDefinition nvarchar(500)
set #ParmDefinition = N'#myOutValue bit OUTPUT'
EXECUTE sp_executesql #SQLString, #ParmDefinition, #myOutValue = #myOut OUTPUT
select #myOut
Update:
To follow up on you comment. If you do not want to modify the original string containing your sql command (e.g. it is used in other places etc) you can wrap that command inside a new string something like:
#SQLString = 'select #myOutValue = (' + #yourOrigSqlCommand + ')'
And call sp_executesql in the same way as above.
I believe this solves your problem.
DECLARE #command nvarchar(max) = 'SELECT CASE WHEN ( SELECT COUNT(*)
FROM [table] WITH ( NOLOCK )
WHERE DATEDIFF(minute, systemupdatedtimestamp, GETDATE()) < 10
) > 0 THEN 0
ELSE 1
END'
exec sp_executesql #command