SQL server use "IF variable LIKE pattern" - sql-server

Why this doesn't work?
DECLARE #str varchar = '######'
IF #str LIKE '%###%' SELECT 1
but this works
IF '######' LIKE '%###%' SELECT 1
UPDATE
why this works
DECLARE #Comment varchar(255) = '[A-B-C-D]'
IF #Comment LIKE '%[%-%-%-%]%' SELECT 1
however this doesn't work?
DECLARE #Comment nvarchar(255) = '[A-B-C-D]'
IF #Comment LIKE '%[%-%-%-%]%' SELECT 1

Add to your variable type length.
DECLARE #str varchar = '######'
IF #str LIKE '%###%' SELECT 1
is the same as (implicit cast will change it to '#')
DECLARE #str varchar(1) = '######'
/* IF '#' LIKE '%###%' SELECT 1 */
IF #str LIKE '%###%' SELECT 1
This will work:
DECLARE #str varchar(20) = '######'
IF #str LIKE '%###%' SELECT 1

try declaring the size of your varchar
DECLARE #str varchar(50) = '######'
SELECT 1 WHERE #str LIKE '%###%'

If you don't use specify type length, it will use mimimum code page length.This contants, varchar 1 and nvarchar 2. So, actually if scope is working normaly.
DECLARE #str varchar = '######'
SELECT DATALENGTH(#str)
DECLARE #str1 varchar(20) = '######'
select DATALENGTH(#str1)
DECLARE #str3 nvarchar = '######'
SELECT DATALENGTH(#str3)
DECLARE #str4 nvarchar(20) = '######'
select DATALENGTH(#str4)

Related

How to store the result of exec in a variable

How can I store the result of exec in a variable? The output is JSON.
My SQL query is complex and dynamically generated, so I have to set a variable and execute it.
create PROCEDURE dbo.RetrievePerfCounterData #jsonOutput NVARCHAR(MAX) OUTPUT
AS
BEGIN
declare #sql NVARCHAR(MAX)
SET #sql = ' SELECT TOP (1) getdate() AS ''dateTime'' ,suser_sname()AS ''user'' FOR JSON PATH '
exec (#sql)
END
Here's my attempt at storing the data in a variable:
DECLARE #json AS NVARCHAR(MAX)
EXEC dbo.RetrievePerfCounterData #jsonOutput = #json OUTPUT
DECLARE #myVar VARCHAR(MAX)
DECLARE #SQL NVARCHAR(MAX)
IF OBJECT_ID('tempdb..#t1') IS NOT NULL DROP TABLE #t1
CREATE TABLE #t1 (col1 INT, col2 INT)
INSERT INTO #t1
SELECT 1, 1
UNION
SELECT 1, 2
SET #SQL = 'SET #myVar = (SELECT * FROM #t1 AS T FOR JSON AUTO);'
EXEC sp_executesql #SQL, N'#myVar VARCHAR(MAX) OUT', #myVar OUT
SELECT #myVar
You need to use a subquery:
SET #json = (SELECT TOP (1) getdate() AS [dateTime],suser_sname()AS [user] FOR JSON PATH);

Concatenate two strings into one without duplicates

I have two strings:
DECLARE #str1 varchar(max) = '[First Name],[Last Name],[Middle Name]'
DECLARE #str2 varchar(max) = '[First Name],[Pin Code],[Address],[Last Name]'
Want to concatenate two strings into one without duplicates.
Expected Output:
str3
-------------------------------------------------------------
[First Name],[Last Name],[Middle Name],[Pin Code],[Address]
You can use STRING_SPLIT() function and DISTINCT as
DECLARE #str1 varchar(max) = '[First Name],[Last Name],[Middle Name]';
DECLARE #str2 varchar(max) = '[First Name],[Pin Code],[Address],[Last Name]';
SELECT DISTINCT *
FROM STRING_SPLIT(#Str1 +','+ #Str2, ',');
Or
DECLARE #str1 varchar(max) = '[First Name],[Last Name],[Middle Name]';
DECLARE #str2 varchar(max) = '[First Name],[Pin Code],[Address],[Last Name]';
SELECT DISTINCT *
FROM STRING_SPLIT(CONCAT(#Str1, ',', #Str2), ',');
to get it as one row
declare #result varchar(max) = '';
SELECT #result = #result + value
FROM STRING_SPLIT(CONCAT(#Str1, ',', #Str2), ',')
group by value;
SELECT #result;
Demo
and since you are working on SQL Server 2008 you need to create your own function such this one here.

"Error converting data type nvarchar to bigint" when executing a stored procedure

I'm trying to execute a stored procedure which inputs 3 parameters selected from a query. The first 2 stored procedure parameters are supposed to be int or bigint, but sql doesn't accept it and tell me it cannot convert type nvarchar to bigint.
So I changed the parameter types to nvarchar but now I get this error when executing a query within the stored procedure. I tried to convert nvarchar to bigint but it doesn't work even though the parameter values are numeric.
Here's how I'm executing the stored procedure:
[dbo].[InsertMultiChoiceList] [PatientRiskAssessmentQuestionsID], NetworkRiskAssessmentQuestionsID, Answer
The parameters being passed on look like these:
230124| 118 |COPD (Chronic Obstructive Pulmonary Disease), Congestive Heart Failure (CHF), Sleep Apnea
Here the definition of my stored procedure:
ALTER PROCEDURE [dbo].[InsertMultiChoiceList]
#PatientRiskAssessmentQuestionsID nvarchar(100),
#NetworkRiskAssessmentQuestionsID nvarchar(100),
#answer varchar(max)
AS
BEGIN
DECLARE #XML AS XML
DECLARE #Delimiter AS CHAR(1) =','
SET #XML = CAST(('<X>'+REPLACE(#answer , #Delimiter ,'</X><X>')+'</X>') AS XML)
DECLARE #temp TABLE (Answer Varchar(max))
INSERT INTO #temp
SELECT N.value('.', 'Varchar(max)') AS Answer
FROM #XML.nodes('X') AS T(N)
INSERT INTO [dbo].[PatientRiskAssessmentQuestionsList](NetworkRiskAssessmentListID, PatientRiskAssessmentQuestionsID)
SELECT
[dbo].[fnc_GetNetworkRiskAssessmentList](LTRIM(RTRIM(q.Answer)), #NetworkRiskAssessmentQuestionsID, 'List') AS NetworkRiskAssessmentListID,
#PatientRiskAssessmentQuestionsID
FROM
(SELECT Answer FROM #temp) q
WHERE
NOT EXISTS (SELECT 1
FROM PatientRiskAssessmentQuestionsList x
WHERE x.NetworkRiskAssessmentListID = NetworkRiskAssessmentListID
AND x.PatientRiskAssessmentQuestionsID = #PatientRiskAssessmentQuestionsID);
END
Here's the structure of the PatientRiskAssessmentQuestionsList table
Here's the script for fnc_GetNetworkRiskAssessmentList
ALTER function [dbo].[fnc_GetNetworkRiskAssessmentList]
(#text varchar(max),
#networkriskquestionid bigint,
#type varchar(20)
)
RETURNS BIGINT
AS
BEGIN
declare #id bigint
declare #questionid bigint
declare #count int
set #id = null
set #questionid = null
set #count = 0
if(#type = 'List')
begin
select #count = Count(*)
from NetworkRiskAssessmentList mc
where mc.Answer = #text
and mc.NetworkRiskAssessmentQuestionsID = #networkriskquestionid
if #count > 0
begin
select top(1) #questionid = mc.NetworkRiskAssessmentListID
from NetworkRiskAssessmentList mc
where mc.Answer = #text
and mc.NetworkRiskAssessmentQuestionsID = #networkriskquestionid
set #id = #questionid
end
end
return #questionid
end
The issue is you are trying to push a string value into the column NetworkRiskAssessmentListID which is actually BIGINT thus SQL doesn't allow the conversion.
Just a sample code to show you the issue
CREATE TABLE #Test
(
Patient BIGINT,
Network BIGINT
)
GO
DECLARE #Patient NVARCHAR(100)
DECLARE #Network NVARCHAR(100)
SET #Patient = '1234'
SET #Network = 'List'
INSERT INTO #Test VALUES (#Patient,#Network)
Hope this helps, try changing the datatype of the table and give it a try.
maybe your data has Enter character or Tab character so use code like below :
DECLARE #XML AS XML
DECLARE #Delimiter AS CHAR(1) =','
SET #XML = CAST(('<X>'+REPLACE(#answer , #Delimiter ,'</X><X>')+'</X>') AS XML)
DECLARE #temp TABLE (Answer Varchar(max))
INSERT INTO #temp
SELECT N.value('.', 'Varchar(max)') AS Answer FROM #XML.nodes('X') AS T(N)
insert into [dbo].[PatientRiskAssessmentQuestionsList](NetworkRiskAssessmentListID, PatientRiskAssessmentQuestionsID)
select
[dbo].[fnc_GetNetworkRiskAssessmentList](LTRIM(RTRIM(q.Answer)), #NetworkRiskAssessmentQuestionsID, 'List') as NetworkRiskAssessmentListID,
#PatientRiskAssessmentQuestionsID
from
(select cast(replace(replace(Answer, char(13), ''), char(10), '') as bigint) as Answer from #temp) q
where not exists
(
select 1 from PatientRiskAssessmentQuestionsList x
where x.NetworkRiskAssessmentListID = NetworkRiskAssessmentListID and x.PatientRiskAssessmentQuestionsID = #PatientRiskAssessmentQuestionsID
);
You are passing PatientRiskAssessmentQuestionsID value to #PatientRiskAssessmentQuestionsID nvarchar(100) parameter
Then you are using it in next code
select 1 from PatientRiskAssessmentQuestionsList x
where x.NetworkRiskAssessmentListID = NetworkRiskAssessmentListID
and x.PatientRiskAssessmentQuestionsID = #PatientRiskAssessmentQuestionsID
so the issue in the AND condition, here
and x.PatientRiskAssessmentQuestionsID = 'PatientRiskAssessmentQuestionsID'
x.PatientRiskAssessmentQuestionsID is bigint
and #PatientRiskAssessmentQuestionsID is nvarchar (100)
its value
[PatientRiskAssessmentQuestionsID]
so fix this one, and everything will be Ok.

Select query using varchar with 'in'

I have this query:
DECLARE #holdIds VARCHAR(MAX)
SET #holdIds = '1,2,3'
DECLARE #flagNames NVARCHAR(MAX);
SELECT
#flagNames = COALESCE(#flagNames + ',', '') + FlagName
FROM
BurnHoldStatus
WHERE
BurnHoldStatusID in (#holdIds);
SELECT #flagNames AS FlagName;
In this example the variable '#holdIds' has values '1,2,3' but could have just one value '1'.
When I run the query, an error appears:
Msg 245, Level 16, State 1, Line 6
Conversion failed when converting the varchar value '1,2,3' to data type int.
I try convert the value of '#holdIds' but not work.
Any idea?
Thanks.
[UPDATE]
I found the answer:
DECLARE #holdIds NVARCHAR(MAX);
SET #holdIds = '1,2,3';
DECLARE #holdIdList TABLE(id INT);
INSERT INTO #holdIdList
SELECT * FROM Split(#holdIds, ',');
DECLARE #flagNames NVARCHAR(MAX);
SELECT
#flagNames = COALESCE(#flagNames + ',', '') + FlagName
FROM
BurnHoldStatus, #holdIdList h
WHERE
BurnHoldStatusID = h.id;
SELECT #flagNames AS FlagName;
In this code I use an function 'Split' to split a string passing the divisor (i.e: ',').
Split function code:
ALTER FUNCTION [dbo].[Split]
(
#RowData nvarchar(MAX),
#SplitOn nvarchar(MAX)
)
RETURNS #RtnValue table
(
Data nvarchar(MAX)
)
AS
BEGIN
Declare #Cnt int
Set #Cnt = 1
While (Charindex(#SplitOn,#RowData)>0)
Begin
Insert Into #RtnValue (data)
Select
Data = ltrim(rtrim(Substring(#RowData,1,Charindex(#SplitOn,#RowData)-1)))
Set #RowData = Substring(#RowData,Charindex(#SplitOn,#RowData)+1,len(#RowData))
Set #Cnt = #Cnt + 1
End
Insert Into #RtnValue (data)
Select Data = ltrim(rtrim(#RowData))
Return
END
Thanks for Vercelli by show other post.
Thanks guys :)
The comment made by swe is correct. You could make the query dynamic, then insert #holdIds See below for a workaround:
DECLARE #holdIds VARCHAR(MAX)
SET #holdIds = '1,2,3'
SET #holdIds = (CHAR(39) + (REPLACE(#holdIds, ',', ''',''') + CHAR(39)))
You can do this, then set the entire query above as a varchar variable, then execute. There are certainly other workarounds as well but dynamic SQL will work.

Split string into three variables in SQL Server 2005

I have an string
declare #s varchar(100),
set #s='aaaa,bbbb,cccc'
declare #first varchar(100),
declare #second varchar(100),
declare #third varchar(100)
Now I need to split these strings into three variable holding there values like this
#first=aaaa
#second=bbbb
#third=cccc
If I am using the split function then I get the output like this
aaaa
bbbb
cccc
Is there any better way we can achieve this result? Any help would be appreciated.
I want this result into a variable because I need it for further processing
Thanks
Here's a quick and dirty hack, assuming that your input strings always follow that format.
DECLARE #s VARCHAR(100)
SET #s = 'aaaa,bbbb,cccc'
DECLARE #first VARCHAR(100)
DECLARE #second VARCHAR(100)
DECLARE #third VARCHAR(100)
SET #s = '<row>' + REPLACE(#s, ',', '</row><row>') + '</row>'
SELECT #first = CONVERT(XML, #s).value('(/row)[1]', 'varchar(100)')
, #second = CONVERT(XML, #s).value('(/row)[2]', 'varchar(100)')
, #third = CONVERT(XML, #s).value('(/row)[3]', 'varchar(100)')
SELECT #first
, #second
, #third
If the split function you're using returns the three values in a table, one option might be to use that output to insert into a table variable with an integer identity, and then pick which variable pairs with which identity value:
DECLARE #first VARCHAR(100)
DECLARE #second VARCHAR(100)
DECLARE #third VARCHAR(100)
declare #split_output table (block varchar(100) )
declare #split_identity table (in_order int identity(1,1), block varchar(100))
/* recreate output of split fn */
insert into #split_output
select 'aaaa'
union
select 'bbbb'
union
select 'cccc'
select * from #split_output
/* push split output into table with identity column */
insert into #split_identity (block)
select block from #split_output
select * from #split_identity
/* Use identity value to pick which row of the table goes with which variable */
set #first = (select block from #split_identity where in_order = 1)
set #second = (select block from #split_identity where in_order = 2)
set #third = (select block from #split_identity where in_order = 3)
select #first, #second, #third
declare #s varchar(100)
set #s='aaaa,bbbb,cccc'
declare #first varchar(100)
declare #second varchar(100)
declare #third varchar(100)
select #first = left(#s, T.C1-1),
#second = substring(#s, T.C1+1, T.C2-T.C1),
#third = stuff(#s, 1, T.C2+1, '')
from (select charindex(',', #s),
len(#s)-charindex(',', reverse(#s))) as T(C1, C2)
String Functions (Transact-SQL)

Resources