CREATE TYPE TableVariable AS TABLE
(
id int identity(1,1),
field_ids INT,
value VARCHAR(MAX)
)
Type created successfully.
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
Alter PROCEDURE Testing
(
#TableVar TableVariable READONLY,
#C_id INT
)
AS
Declare #maxPK INT;
Declare #pk INT;
Declare #fid INT;
Declare #val VARCHAR(max);
Declare #Where VARCHAR(max);
Declare #SQL VARCHAR(MAX);
Set #pk = 1
BEGIN
BEGIN TRY
SET NOCOUNT ON;
Select #maxPK = count(*) From #TableVar
SELECT #maxPK
SELECT #C_id
Set #SQL = 'SELECT DISTINCT v1.e_id from values v1 inner join listings l ON v1.e_id =
l.e_id WHERE l.c_id='+ #C_id
SELECT #SQL
While #pk <= #maxPK
BEGIN
SELECT #fid= field_ids FROM #TableVar where id=#pk;
SELECT #val= value FROM #TableVar where id=#pk;
SELECT #fid
SELECT #val
SET #SQL += ' and exists (select 1 from values v#pk+1 where v1.e_id = #pk+1.e_id and #pk+1.f_id=#fid and(value=#val))'
Select #pk = #pk + 1
END
SELECT #SQL
EXECUTE SP_EXECUTESQL #SQL
END TRY
BEGIN CATCH
END CATCH
END
DECLARE #DepartmentTVP AS TableVariable;
INSERT INTO #DepartmentTVP VALUES (14567, 'first')
INSERT INTO #DepartmentTVP VALUES (145678, 'second')
SELECT *
FROM #DepartmentTVP
EXEC Testing #DepartmentTVP, 83
I executed the above procedure.Values are not passed to the query
This is my orginal query
select distinct
v1.e_id
from
values v1
inner join
listings l on v1.e_id = l.e_id
where
l.c_id = 83
and exists (select 1
from values v2
where v1.e_id = v2.e_id
and v2.f_id = 1780
and (value = N'Peppermint Whole Care Toothpaste'))
and exists (select 1
from values v3
where v1.e_id = v3.e_id
and v3.f_id = 22483
and (value = N'sasdfa'))
order by
l.id desc
and exists part will add dynamically.
If you are wanting a variable to be part of the text such as:
'select 1 from values v#pk+1 where v1.e_id = #pk+1.e_id'
Then you need to escape the string and add the variable -- but beware this is prone to SQL Injection attacks if you don't strictly control the source of the variable data!
Example:
'select 1 from values v'+convert(varchar(15),#pk+1)+' where v1.e_id = '+convert(varchar(15),#pk+1)+'.e_id'
If you simply want to pass the variable into the string such as:
'and v5.f_id=#fid and(value=#val))'
Then you leave those variables unescaped, and pass them into sp_executesql
Example:
exec sp_executesql #SQL, N'#fid int, #val varchar(max)', #fid=#fid, #val=#val
More info on sp_executesql and its parameters:
https://learn.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sp-executesql-transact-sql
Related
I need split this string using stored Procedure in MySQL 8 version
"John;Elizabeth;Mark;Zagor;Annie;Lucy;Peter;Robin;Wilson;Tom;Bettie;Myriam;Frankie;Nick;Marilyn"
The string values are separated by a semicolon.
My sProc below.
The problem it's in output.
The first name splitted on this string it's Elizabeth and not John.
Where is it John?
All other names are present in output of sProc, only John is missing...
What am I doing wrong?
BEGIN
DECLARE tNameSeries LONGTEXT;
DECLARE t_tNameSeries LONGTEXT;
SET tNameSeries = "John;Elizabeth;Mark;Zagor;Annie;Lucy;Peter;Robin;Wilson;Tom;Bettie;Myriam;Frankie;Nick;Marilyn";
WHILE LOCATE(";",tNameSeries) > 0 DO
SET tNameSeries = REPLACE (tNameSeries, (SELECT LEFT(tNameSeries,LOCATE(";",tNameSeries))),'');
SET t_tNameSeries = SUBSTRING_INDEX(tNameSeries,";",1);
SELECT t_tNameSeries;
END WHILE;
END
update
Using ths edit sProc the output is only John
BEGIN
DECLARE tNameSeries LONGTEXT;
DECLARE t_tNameSeries LONGTEXT;
SET tNameSeries = "John;Elizabeth;Mark;Zagor;Annie;Lucy;Peter;Robin;Wilson;Tom;Bettie;Myriam;Frankie;Nick;Marilyn";
WHILE LOCATE(";",tNameSeries) > 0 DO
SET t_tNameSeries = SUBSTRING_INDEX(tNameSeries,";",1);
SET tNameSeries = REPLACE (t_tNameSeries, (SELECT LEFT(t_tNameSeries,LOCATE(";",t_tNameSeries))),'');
SELECT tNameSeries;
END WHILE;
END
SELECT *
FROM JSON_TABLE(
CONCAT(
'["',
REPLACE(
"John;Elizabeth;Mark;Zagor;Annie;Lucy;Peter;Robin;Wilson;Tom;Bettie;Myriam;Frankie;Nick;Marilyn",
';',
'","'
),
'"]'
),
'$[*]' COLUMNS (
id FOR ORDINALITY,
name VARCHAR(255) PATH '$'
)
) jsontable;
https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=546907fc5c00b7173fa73327fdd97638
Insert it into the SP if needed.
This works too:
set #names = 'John;Elizabeth;Mark;Zagor;Annie;Lucy;Peter;Robin;Wilson;Tom;Bettie;Myriam;Frankie;Nick;Marilyn';
select
substring_index(substring_index(#names,';',R),';',-1) W
from (select row_number() over () as R
from information_schema.tables) x
where x.R<=1+length(#names)-length(replace(#names,';',''));
see: https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=5cc442be9da54d8cbcdbabc58ee37b65
I've a cursor which fetch dynamic number of columns because the "SELECT STATEMENT" which I use to declare this cursor is dynamic.
Since I do not know at any point of time, how many columns this cursor will have, I cannot declare fixed number of variables into fetch.
So I have built FETCH statement as dynamic and stored in one #variable... but when i run fetch statement using EXEC sp_executesql
its failing with error ..Must declare the scalar variable "#objcursor".
I know that #objcursor variable is not accessible becasue while sp_executesql run which run on isolate THREAD
is there any way someone can advise, how to handle this code to run without an error?
Here is my T-SQL code:
/* ==== Variable Declaration ==== */
declare #AllValues nvarchar(max)
declare #objcursor as cursor
declare #MonthCount integer
declare
#vsql as nvarchar(max)
,#vquery as nvarchar(max)
,#id as int
,#value as varchar(50)
BEGIN
SELECT #AllValues = CASE
WHEN t.column_id=1 THEN
(COALESCE(#AllValues +'"', '')+ t.name)+'"'
WHEN t.column_id > 1 THEN
(COALESCE(#AllValues + ',"', '') + t.name)+'"'
END
FROM
(
SELECT sc.name, sc.column_id FROM sys.objects o
INNER JOIN sys.columns sc ON o.object_id = sc.object_id
WHERE o.name = 'temp_daywise' AND o.type = 'U' AND (sc.name like '%Curr Yr%' or column_id=1)
) AS t
ORDER BY t.column_id
SET #AllValues='SELECT "'+#AllValues+' FROM dbo.temp_daywise'
set #vquery = #AllValues
set #vsql = 'set #cursor = cursor forward_only static for ' + #vquery + ' open #cursor;'
exec sys.sp_executesql
#vsql
,N'#cursor cursor output'
,#objcursor output
---Handling Dynamic number of columns in a cursor, get the column count first and build FETCH statement dynamically
Select #CurCount=COUNT(*) from sys.columns where object_id in(
SELECT object_id from sys.objects where name = 'dbo.temp_daywise' and type = 'U' )
and (name like '%Curr Yr%');
SET #LoopCount = 1
--here building my fetch statement
SET #fetchsql ='fetch next from #objcursor into #AgreementID'
WHILE #LoopCount <= #CurCount
BEGIN
SET #fetchsql = #fetchsql+','+'#CY_Day'+CONVERT(VARCHAR(2),#LoopCount)
SET #LoopCount = #LoopCount + 1
END
--EXEC #fetchsql
EXEC sp_executesql #fetchsql
while (##fetch_status = 0)
begin
BEGIN
'update ...here something'
END
EXEC #fetchsql
end
close #objcursor
deallocate #objcursor
END
Here is my data and expected resullts:
1) My dynamic cusror will read column name from sys.columns because coulmns are not static that's based on columns count I'm building FETCH statement. following code build cusrsor SELECT statement
SELECT #AllValues = CASE
WHEN t.column_id=1 THEN
(COALESCE(#AllValues +'"', '')+ t.name)+'"'
WHEN t.column_id > 1 THEN
(COALESCE(#AllValues + ',"', '') + t.name)+'"'
END
FROM
(
SELECT sc.name, sc.column_id FROM sys.objects o
INNER JOIN sys.columns sc ON o.object_id = sc.object_id
WHERE o.name = 'temp_daywise' AND o.type = 'U' AND (sc.name like '%Curr Yr%' or column_id=1)
) AS t
ORDER BY t.column_id
SET #AllValues='SELECT "'+#AllValues+' FROM dbo.temp_daywise'
set #vquery = #AllValues
set #vsql = 'set #cursor = cursor forward_only static for ' + #vquery + ' open #cursor;'
exec sys.sp_executesql
#vsql
,N'#cursor cursor output'
,#objcursor output
2) I want to update fetch data into following table for columns Day1...Day31. if cusrsor found 20 columns data will update until CY_Day20.
3) In short, i do not know the cusror retrieving columns at design time so i can't produce fetching variable. Since columns are known at run tiume, i have to build fetch & update statment in while loop as like below:
Note: ignore DECLARE which is on start of the code... but i placed here to get an idea.
DECLARE
#CY_Day1 Numeric(18,2), #CY_Day2 Numeric(18,2), #CY_Day3 Numeric(18,2), #CY_Day4 Numeric(18,2), #CY_Day5 Numeric(18,2),
, #CY_Day7 Numeric(18,2), #CY_Day8 Numeric(18,2), #CY_Day9 Numeric(18,2), #CY_Day10 Numeric(18,2), #PY_Day10 Numeric(18,2), #CY_Day11 Numeric(18,2), #CY_Day12 Numeric(18,2),........ #CY_Day31 Numeric(18,2)
Select #CurCount=COUNT(*) from sys.columns where object_id in(
SELECT object_id from sys.objects where name = 'dbo.temp_daywise' and type = 'U' )
and (name like '%Curr Yr%');
SET #LoopCount = 1
SET #fetchsql ='fetch next from #objcursor into #AgreementID'
SET #updatesql ='UPDATE dbo.TPDD_Report_Monthly_Details SET '
WHILE #LoopCount <= 2
BEGIN
SET #fetchsql = #fetchsql+','+'#CY_Day'+CONVERT(VARCHAR(2),#LoopCount)
SET #updatesql= #updatesql +'CY_Day'+CONVERT(VARCHAR(2),#LoopCount)+' = #CY_Day'+CONVERT(VARCHAR(2),#LoopCount)+',CY_TPDD_Day'+CONVERT(VARCHAR(2),#LoopCount)+' = (#CY_Day'+CONVERT(VARCHAR(2),#LoopCount)+'/1/1),'
SET #LoopCount = #LoopCount + 1
END
SET #updatesql =#updatesql + ' dss_update_time = #v_dss_update_time WHERE AgreementId = #AgreementID and TpddYear=CONVERT(VARCHAR(4),#Current_year)+CONVERT(VARCHAR(4),#Previous_year) and Running_Month = #MonthNo'
--EXEC #fetchsql
PRINT #fetchsql
PRINT #updatesql
---executing FETCH statement
EXEC sp_executesql #fetchsql
while (##fetch_status = 0)
begin
BEGIN
---updating table columns
EXEC sp_executesql #updatesql
END
EXEC #fetchsql
end
close #objcursor
deallocate #objcursor
Finally my cusrsor fetch & udpate statement will looks like below:
fetch next from #objcursor into #AgreementID,#CY_Day1,#CY_Day2,#CY_Day3,#CY_Day4,#CY_Day5,#CY_Day6,#CY_Day7,#CY_Day8,#CY_Day9,#CY_Day10
UPDATE dbo.TPDD_Report_Monthly_Details SET
CY_Day1 = #CY_Day1, CY_TPDD_Day1 = (#CY_Day1/1/1),
CY_Day2 = #CY_Day2, CY_TPDD_Day2 = (#CY_Day2/1/1),
CY_Day3 = #CY_Day3, CY_TPDD_Day3 = (#CY_Day3/1/1),
CY_Day4 = #CY_Day4, CY_TPDD_Day4 = (#CY_Day4/1/1),
CY_Day5 = #CY_Day5, CY_TPDD_Day5 = (#CY_Day5/1/1),
CY_Day6 = #CY_Day6, CY_TPDD_Day6 = (#CY_Day6/1/1),
CY_Day7 = #CY_Day7, CY_TPDD_Day7 = (#CY_Day7/1/1),
CY_Day8 = #CY_Day8, CY_TPDD_Day8 = (#CY_Day8/1/1),
CY_Day9 = #CY_Day9, CY_TPDD_Day9 = (#CY_Day9/1/1),
CY_Day10 = #CY_Day10, CY_TPDD_Day10 = (#CY_Day10/1/1),
dss_update_time = #v_dss_update_time
WHERE AgreementId = #AgreementID
Hope I;m able to present my problem correctly.
I have a good start. You're probably going to have to tweak a few things. I did my best to get it as close as possible as your actual situation. Hope this helps. If you have any questions, let me know.
NOTE I USE THE SAME TABLE NAMES AND DROP THEM.
IF OBJECT_ID('dbo.temp_daywise') IS NOT NULL
DROP TABLE dbo.temp_daywise;
IF OBJECT_ID('dbo.TPDD_report_Monthly_Details') IS NOT NULL
DROP TABLE dbo.TPDD_report_Monthly_Details;
CREATE TABLE dbo.temp_daywise
(
AgreementID CHAR(6),
RunningMonth INT,
[Curr Yr1] VARCHAR(100),
[Curr Yr2] VARCHAR(100),
[Curr Yr3] VARCHAR(100)
);
INSERT INTO temp_daywise
VALUES ('A10001',3,'col1_1','col2_1','col3_1'),
('A10003',3,'col1_2','col2_2','col3_2'),
('A10006',3,'col1_3','col2_3','col3_3'),
('A10008',3,'col1_4','col2_4','col3_4');
CREATE TABLE dbo.TPDD_report_Monthly_Details
(
TpddYear DATE,
AgreementID CHAR(6),
RunningMonth INT,
[CY_Day1] VARCHAR(100),
[CY_Day2] VARCHAR(100),
[CY_Day3] VARCHAR(100)
);
INSERT INTO TPDD_report_Monthly_Details
VALUES ('20131220','A10001',3,NULL,NULL,NULL),
('20131220','A10003',3,NULL,NULL,NULL),
('20131220','A10006',3,NULL,NULL,NULL),
('20131220','A10008',3,NULL,NULL,NULL);
--Now that I've created my versions of your table, here's the actual code
--Variable to hold columns that need to be updated
DECLARE #ColToBeUpdated VARCHAR(MAX);
--Gets your column information for temp_daywise
WITH CTE_temp_daywise_Cols
AS
(
SELECT *
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'temp_daywise'
)
--Now join temp_daywise columns to TPDD_report columns
--QUOTENAME() add's brackets [] around each column
SELECT #ColToBeUpdated = COALESCE(#ColToBeUpdated + ',','') + QUOTENAME(A.COLUMN_NAME) + ' = B.' + QUOTENAME(B.COLUMN_NAME)
FROM INFORMATION_SCHEMA.COLUMNS A
INNER JOIN CTE_temp_daywise_Cols B
--The "+1" compensates for difference in ordinal positions
ON A.Ordinal_Position = B.ORDINAL_POSITION + 1
--This makes the table alisaed A to only get columns for TPDD_report
WHERE A.TABLE_NAME = 'TPDD_report_Monthly_Details'
--Don't return AgreementID
AND A.COLUMN_NAME != 'AgreementID'
AND B.COLUMN_NAME != 'AgreementID'
ORDER BY A.ORDINAL_POSITION
--Variable to hold code
DECLARE #sql VARCHAR(MAX);
SELECT #sql = 'UPDATE dbo.TPDD_Report_Monthly_Details
SET ' + #ColToBeUpdated +'
FROM dbo.TPDD_Report_Monthly_Details AS A
INNER JOIN temp_daywise AS B
ON A.AgreementID = B.AgreementID'
--Look at code
--Notice you can join on AgreementID and just set the columns equal to each other
SELECT #sql;
--To execute
--EXEC(#sql)
Results stored in #sql:
UPDATE dbo.TPDD_Report_Monthly_Details
SET [RunningMonth] = B.[RunningMonth],
[CY_Day1] = B.[Curr Yr1],
[CY_Day2] = B.[Curr Yr2],
[CY_Day3] = B.[Curr Yr3]
FROM dbo.TPDD_Report_Monthly_Details AS A
INNER JOIN temp_daywise AS B
ON A.AgreementID = B.AgreementID
I am creating a view using another view inner join(ed) with a table valued function ,
this table valued function calls a Scalar valued function to populate one of its column, when I execute the same,
i get error stating : Maximum stored procedure, function, trigger, or view nesting level exceeded(limit 32)
can anyone help .....plz
*Below is the table valued function
ALTER FUNCTION [dbo].[sstfnAllSubjectWithAASDID]
(
)
RETURNS
#tt TABLE
(
AASDID numeric(18,0),
SubjectString nvarchar(MAX),
SubjectCount int
)
AS
BEGIN
declare #pID numeric(18,0)
declare #pStr nvarchar(MAx)
declare #pCount int
Declare LAASDID Cursor Read_Only Fast_Forward for (SELECT AASDid from vwAcdAdmissionSessionDetailWithAcdAdmissionSessionSubjectDetail)
open LAASDID
FETCH next from LAASDID into #pID
while(##FETCH_STATUS =0)
BEGIN
set #pCount = (SELECT COUNT( MasterSubject.SubjectName ) as cnt
FROM AcdAdmissionSessionSubjectDetail INNER JOIN
MasterSubject ON AcdAdmissionSessionSubjectDetail.SubjectId = MasterSubject.SubjectId where
AcdAdmissionSessionSubjectDetail.AASDID = #pID
)
set #pStr = (SELECT [dbo].[ssspfnGetSubjectname] (#pID))
Insert Into #tt (AASDID,SubjectString,SubjectCount) values (#pID,#pStr,#pCount)
FETCH next from LAASDID into #pID
END
RETURN
END
And this is the scalar valued function which it calls
ALTER FUNCTION [dbo].[ssspfnGetSubjectname]
(
#pAASDID numeric(18,0)
)
RETURNS nvarchar(max)
AS
BEGIN
DECLARE #Cols1 as nvarchar(max)
set #Cols1 = STUFF( (SELECT DISTINCT SubjectName + ','
FROM ( SELECT AcdAdmissionSessionSubjectDetail.AASDID, MasterSubject.SubjectName as SubjectName
FROM AcdAdmissionSessionSubjectDetail INNER JOIN
MasterSubject ON AcdAdmissionSessionSubjectDetail.SubjectId = MasterSubject.SubjectId where
AcdAdmissionSessionSubjectDetail.AASDID = #pAASDID
) as ss
FOR XML PATH('')) ,1,1,'')
RETURN #Cols1
END
Try this code
SP_CONFIGURE 'nested_triggers',0
GO
RECONFIGURE
GO
I'm creating a stored procedure which gets some parameters and in turn these parameters are sent to another stored procedure which I'm calling from openrowset but I'm getting some syntax errors.
CREATE PROCEDURE UpdatePrevFYConfigData
-- Add the parameters for the stored procedure here
#startDate datetime,
#endDate datetime,
#productGroup varchar(8000) = 'All',
#projectType varchar(500) = 'All',
#businessUnit nvarchar(50) = 'All',
#developmentLocation nvarchar(100) = 'All'
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
declare #start varchar(50)
declare #end varchar(50)
set #start = cast(#startDate as varchar(40))
set #end = cast(#endDate as varchar(40))
-- Insert statements for procedure here
select round(avg(a.DeviationDeadline),2) as DeviationDeadline,
round(avg(a.DeviationDefinition),2) as DeviationDefinition,
round(avg(a.DeviationRDCosts),2) as DeviationRDCosts,
round(avg(a.FunctionsAdded) + avg(a.FunctionsDeleted),2) as NotRealizedFuncs,
round(avg(a.DeviationPM2000Aufwand),2) as DeviationPM200Aufwand,
round(avg(b.Defect),2) as Defect
into #tempTable
from openrowset('SQLNCLI',
'Server=.\sqlexpress;Trusted_Connection=yes;',
'SET NOCOUNT ON;SET FMTONLY OFF;EXEC [BSC_DB].dbo.SelectScorecardGraphData
'''+#start+''',
'''+#end+''',
'''+#productGroup+''',
'''+#projectType+''',
''1'',
''0'',
''All'',
''Current'',
'''+#businessUnit+''',
'''+#developmentLocation+'''
') as a,
openrowset('SQLNCLI', 'Server=.\sqlexpress;Trusted_Connection=yes;', 'SET NOCOUNT ON;SET FMTONLY OFF;EXEC [BSC_DB].dbo.GetSPCDefectDistributionData
'''+cast(#startDate as varchar(40))+''',
'''+cast(#endDate as varchar(40))+''',
''Defect'',
'''+#projectType+''',
'''+#productGroup+''',
'''+#businessUnit+''',
'''+#developmentLocation+'''') as b
update dbo.EA_ProcessScorecard_Config_Tbl
set EPC_Deviation = case EPC_Metric
when 'PM200' then (select DeviationDefinition from #tempTable)
when 'PM300' then (select DeviationDeadline from #tempTable)
when 'Cost' then (select DeviationRDCosts from #tempTable)
when 'PM150' then (select DeviationPM200Aufwand from #tempTable)
when 'Defect' then (select Defect from #tempTable)
when 'Funcs' then (select NotRealizedFuncs from #tempTable)
END
where EPC_Description = 'PrevFY' and EPC_FYYear = '0'
drop table #tempTable
END
GO
I'm not able to create it and I get the error message:
Msg 102, Level 15, State 1, Procedure UpdatePrevFYConfigData,
Line 38 Incorrect syntax near '+'.
... but if I use hard coded values for the parameters it works!!
Please help!
Both OPENROWSET and OPENDATASOURCE should be used only for accessing external data for, let's say, quick and dirty solutions, or when it is not possible to configure a permanent linked server. These functions do not provide all of the functionality available from a linked server.
The arguments of OPENROWSET and OPENDATASOURCE do not support variables. They have to be specified as string-literal. If variables need to be passed in as arguments to these functions, a query string containing these variables can be constructed dynamically and executed using the EXEC statement.
Similar to (not syntax checked)
DECLARE #sqlCommand varchar(1000)
SET #sqlCommand = 'SELECT *
FROM OPENROWSET(''SQLNCLI'',''server=.\sqlexpress;Trusted_Connection=yes'',''SET NOCOUNT ON;SET FMTONLY OFF;EXEC [BSC_DB].dbo.SelectScorecardGraphData ''''' + cast(#param1 as varchar(10)) + ''''',''' + cast(#param2 as varchar(n)) ''')'
EXEC #sqlCommand
And so on...
Hope that helps. Kind regards,
Stefan
-- FOR USING OPENROWSETS
EXEC sp_configure 'Ad Hoc Distributed Queries'
,1
RECONFIGURE
DECLARE #SQL NVARCHAR(MAX)
SET #SQL = 'INSERT INTO #TABLESIZESYEAR SELECT NULL AS [TABLE NAME], * FROM OPENROWSET
(''SQLOLEDB'',''Server=(local);TRUSTED_CONNECTION=YES;'',''set fmtonly off EXEC one.[dbo].[InvestigateDataGrowthByYearAndClient] #pDATECOLUMN =' + #YEARCOLUMN + ' ,
#pTABLENAME = ' + #TABLENAME + ' WITH RESULT SETS(
([YEAR NAME] NVARCHAR(5) NULL
, [NUMBER OF ROWS] CHAR(11)
, [RESERVED SPACE] VARCHAR(18)
, [DATA SPACE] VARCHAR(18)
, [INDEX SIZE] VARCHAR(18)
, [UNUSED SPACE] VARCHAR(18) )
)
;'') '
DECLARE #ParmDefinition NVARCHAR(500) = '#pDATECOLUMN NVARCHAR(20)
,#YEARCOLUMN NVARCHAR(20)
,#pTABLENAME NVARCHAR(60)';
EXECUTE sp_executesql #sql
,#ParmDefinition
,#YEARCOLUMN = #YEARCOLUMN
,#pDATECOLUMN = #YEARCOLUMN
,#pTABLENAME = #TABLENAME
We have an stored procedure that we created so that user can write comma separated search tags in their software product's admin. So he can add comma-separated tags and in case if he wants to edit them, we read from the table all the tags, recreate them as comma-separated values (CSV) in stored procedure and returns that to the calling code. What happened recently, the user complained that he could not see the new CSVs he wrote. I looked into it and found out that the stored procedure is truncating the string when it reads values from database and creates CSV string. The string is of type nvarchar, and because its exceeding the max characters of 4000 limit, the values gets truncated. Any ideas on how to work out that problem.
Find my code underneath.
BEGIN
BEGIN
Declare #Synonyms Table
(
RowID int Identity(1,1),
SynonymID int,
[Synonym] nvarchar(4000)
);
SET NOCOUNT ON;
Insert #Synonyms(SynonymID, [Synonym])
Select distinct SynonymID, [Synonym] From RF_SearchSynonyms with(nolock) Where SearchTermID = #SearchTermID And ActiveInd = 1
If((Select COUNT(RowID) From #Synonyms) <> 0)
BEGIN
Declare #CurrentRow int = (Select MIN(RowID) From #Synonyms),
#TotalRows int = (Select MAX(RowID) From #Synonyms),
#Synonyms_CSV nvarchar(4000) = '';
WHILE #CurrentRow <= #TotalRows
BEGIN
Declare #TempSyn nvarchar(500);
Select #TempSyn = [Synonym] + ',' From #Synonyms Where RowID = #CurrentRow;
Set #Synonyms_CSV = #Synonyms_CSV + LTRIM(RTRIM(LOWER(#TempSyn)));
SET #CurrentRow = #CurrentRow + 1
END
END
Else
BEGIN
Set #Synonyms_CSV = '';
END
END
BEGIN
Declare #SKUs Table
(
RowID int Identity(1,1),
SkuID int,
SKU nvarchar(15)
);
SET NOCOUNT ON;
Insert #SKUs(SkuID, SKU)
Select distinct SkuID, SKU From RF_SearchSkus with(nolock) Where SearchTermID = #SearchTermID And ActiveInd = 1
If((Select COUNT(RowID) From #SKUs) <> 0)
BEGIN
Declare #CurrentRow1 int = (Select MIN(RowID) From #SKUs),
#TotalRows1 int = (Select MAX(RowID) From #SKUs),
#Skus_CSV nvarchar(4000) = '';
WHILE #CurrentRow1 <= #TotalRows1
BEGIN
Declare #TempSku nvarchar(15);
Select #TempSku = SKU + ',' From #SKUs Where RowID = #CurrentRow1;
Set #Skus_CSV = #Skus_CSV + LTRIM(RTRIM(#TempSku));
SET #CurrentRow1 = #CurrentRow1 + 1
END
END
Else
BEGIN
Set #Skus_CSV = '';
END
END
BEGIN
Declare #Combined varchar(8000),
#syn_len int = 0,
#sku_len int = 0;
Select #syn_len = LEN(#Synonyms_CSV);
Select #sku_len = LEN(#Skus_CSV);
Select #Combined = #Synonyms_CSV + '-_-' + #Skus_CSV;
Select #Synonyms_CSV + '-_-' + #Skus_CSV;
END
END
I can't use text and ntext as they do not play nice with concatenation operations.
Thanks.
How are your declaring the string parameter?
nvarchar(max)
supports up to 2^32-1 (2GB)
See this link.