A Select statement that assigns a value to a variable must not be combined with data-retrieval (No data retrieval involved) - sql-server-2008-r2

DECLARE #a bit;
DECLARE #b bit;
DECLARE #c bit;
SELECT
#a = flagA, #b = flagB,
CASE WHEN flagC is null then #c = 0 ELSE #c = 1 END
FROM Table
The query above throw the exception as stated in the title. Correct me if im wrong but seems to me there is no data retrieval involved in the above statement?

You have to assign the value to #c like this:
SELECT
#a = flagA,
#b = flagB,
#c = (CASE WHEN flagC IS NULL THEN 0 ELSE 1 END)
FROM table

Related

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 to use a T-SQL UDF in a SELECT or UPDATE statement?

Context: SQL Server 2000
I've written a UDF that gives me the text between two other texts, viz
CREATE FUNCTION dbo.StrBetween
(
#Text nvarchar(4000),
#Lhs nvarchar(4000),
#Rhs nvarchar(4000)
)
RETURNS nvarchar(4000)
AS
BEGIN
DECLARE #LhsOffset INT;
DECLARE #RhsOffset INT;
DECLARE #Result NVARCHAR(4000);
SET #LhsOffset = CHARINDEX( #Lhs, #Text );
IF #LhsOffset = 0
BEGIN
RETURN #Text;
END
SET #Result = SUBSTRING( #Text, #LhsOffset+1, LEN(#Text)-LEN(#Lhs));
SET #RhsOffset = CHARINDEX( #Rhs, #Result );
IF #RhsOffset = 0
BEGIN
RETURN #Result;
END
SET #Result = SUBSTRING( #Result, 1, #RhsOffset - 1 );
RETURN #Result;
END
This works fine in SQL Query Analyser if I have, say,
SELECT dbo.StrBetween('dog','d','g')
However, when I pass a column in as the value of the first argument, I get no response. For example,
SELECT [TEST].[dbo].StrBetween(Referrer,'//', '/') as tst FROM tblTest
Referrer is declared as an nvarchar field. I'm a newbie when it comes to T-SQL. What obvious thing am I not seeing?
It's not an issue with calling - it's a logic issue, and the fact that your #Rhs value is part of the #Lhs value.
SET #Result = SUBSTRING( #Text, #LhsOffset+1, LEN(#Text)-LEN(#Lhs));
This is removing the first character of your #Lhs string. However, since the second character is /, and that's what your #Rhs match is searching for, it immediately finds it at position 1 and so you get an empty string.
Instead, try:
SET #Result = SUBSTRING( #Text, #LhsOffset+LEN(#Lhs), 4000);
You don't have to be exact with computing a length. If you ask for 4000 characters and the string is only 12 characters long, SUBSTRING will give you back at most 12 characters. So don't bother computing the new length.

Add comma every nth character in value

my problem is pretty simple. I get a value from a sql select which looks like this:
ARAMAUBEBABRBGCNDKDEEEFOFIFRGEGRIEISITJPYUCAKZKG
and I need it like this:
AR,AM,AU,BE,BA,BR,BG,CN,DK,DE,EE,FO,FI,FR,GE,GR,IE,IS,IT,JP,YU,CA,KZ,KG
The length is different in each dataset.
I tried it with format(), stuff() and so on but nothing brought me the result I need.
Thanks in advance
With a little help of a numbers table and for xml path.
-- Sample table
declare #T table
(
Value nvarchar(100)
)
-- Sample data
insert into #T values
('ARAMAU'),
('ARAMAUBEBABRBGCNDKDEEEFOFIFRGEGRIEISITJPYUCAKZKG')
declare #Len int
set #Len = 2;
select stuff(T2.X.value('.', 'nvarchar(max)'), 1, 1, '')
from #T as T1
cross apply (select ','+substring(T1.Value, 1+Number*#Len, #Len)
from Numbers
where Number >= 0 and
Number < len(T1.Value) / #Len
order by Number
for xml path(''), type) as T2(X)
Try on SE-Data
Time to update your resume.
create function DontDoThis (
#string varchar(max),
#count int
)
returns varchar(max)
as
begin
declare #result varchar(max) = ''
declare #token varchar(max) = ''
while DATALENGTH(#string) > 0
begin
select #token = left(#string, #count)
select #string = REPLACE(#string, #token, '')
select #result += #token + case when DATALENGTH(#string) = 0 then '' else ',' end
end
return #result
end
Call:
declare #test varchar(max) = 'ARAMAUBEBABRBGCNDKDEEEFOFIFRGEGRIEISITJPYUCAKZKG'
select dbo.DontDoThis(#test, 2)
gbn's comment is exactly right, if not very diplomatic :) TSQL is a poor language for string manipulation, but if you write a CLR function to do this then you will have the best of both worlds: .NET string functions called from pure TSQL.
I believe this is what QQping is looking for.
-- select .dbo.DelineateEachNth('ARAMAUBEBABRBGCNDKDEEEFOFIFRGEGRIEISITJPYUCAKZKG',2,',')
create function DelineateEachNth
(
#str varchar(max), -- Incoming String to parse
#length int, -- Length of desired segment
#delimiter varchar(100) -- Segment delimiter (comma, tab, line-feed, etc)
)
returns varchar(max)
AS
begin
declare #resultString varchar(max) = ''
-- only set delimiter(s) when lenght of string is longer than desired segment
if LEN(#str) > #length
begin
-- continue as long as there is a remaining string to parse
while len(#str) > 0
begin
-- as long as know we still need to create a segment...
if LEN(#str) > #length
begin
-- build result string from leftmost segment length
set #resultString = #resultString + left(#str, #length) + #delimiter
-- continually shorten result string by current segment
set #str = right(#str, len(#str) - #length)
end
-- as soon as the remaining string is segment length or less,
-- just use the remainder and empty the string to close the loop
else
begin
set #resultString = #resultString + #str
set #str = ''
end
end
end
-- if string is less than segment length, just pass it through
else
begin
set #resultString = #str
end
return #resultString
end
With a little help from Regex
select Wow=
(select case when MatchIndex %2 = 0 and MatchIndex!=0 then ',' + match else match end
from dbo.RegExMatches('[^\n]','ARAMAUBEBABRBGCNDKDEEEFOFIFRGEGRIEISITJPYUCAKZKG',1)
for xml path(''))