T-SQL function with dynamic SELECT (not possible) - solved with procedure instead - function

I've managed to use EXEC sp_executesql in a one off statement to do a dynamic lookup, but am unable to adjust the code to create a function since EXEC is not allowed in functions. It works in procedures and I've managed to get output via PRINT for a single lookup by using a temporary table, but really that was just me struggling to find a workaround. Ideally I'd like to be able to create a scalar-value function.
The reason that I need a dynamic lookup is because the column name is stored in another table.
Here's a quick breakdown of the tables:
Questions:
Columns: Q_Group, Q_Nbr, Question_Desc, Data_Field
Sample data: 'R3', 5, 'Do you have any allergies?', 'TXT_04'
Responses:
Columns: Order_Nbr, Q_Group, TXT_01, TXT_02, TXT_03, TXT_04, etc.
Data: 999, 'R3', 'blah', 'blah', 'blah', 'NO'
Orders will be assigned a particular set of questions 'Q_Group' and often a particular question will be the same across various different sets of questions. The problem is that when the set/groups of questions were set up, the questions may not have been added in the same order, and thus the responses go into different columns.
So here's where I'm at...
I can get 'TXT_04' from the Data_Field column in Questions and use EXEC sp_executesql to do a lookup for a single order, but am struggling to find a way to accomplish this as a function of some sort.
DECLARE #col_name VARCHAR(6)
DECLARE #sql VARCHAR(100)
SET #col_name = SELECT Data_Field FROM QUESTIONS WHERE Q_Group = 'R3'
AND Question_Desc = 'Do you have any allergies?'
SET #sql = 'SELECT ' + #col_name + ' FROM RESPONSES WHERE Order_Nbr = 999'
EXEC sp_executesql #sql
I'm just at a loss as to how this could be incorporated into a function so that I could get responses for several orders in a result set. Any workarounds possible? Maybe I'm totally off base using EXEC sp_executesql?
Thanks.
Edit...
Okay, I've changed the title to reflect that I'm going to consider this solved with a procedure instead of a function, as it ended up getting the output that I wanted. Which was a table with all of the corresponding responses.
Here's the code that I settled on. I decided to use LIKE to match the Question_Desc instead of equals, and then included the Question_Desc in the results, so that it could be used a bit more broadly. Thankfully it's pretty quick to run currently. Although that could always change as the database grows!
CREATE PROCEDURE get_all_responses (#question_txt VARCHAR(255))
AS
DECLARE #response_col VARCHAR(35)
DECLARE #t TABLE (order_nbr int, question_txt VARCHAR(255), response_col VARCHAR(35), response VARCHAR(255))
DECLARE #i TABLE (id INT PRIMARY KEY IDENTITY(1,1), response_col VARCHAR(35))
DECLARE #u TABLE (order_nbr int, response VARCHAR(255))
DECLARE #sql VARCHAR(200)
INSERT #t
SELECT Order_Nbr, Question_Desc, Data_Field, NULL
FROM Responses
JOIN (
SELECT Q_Group, Question_Desc, Data_Field
FROM Questions
WHERE Question_Desc LIKE #question_txt
) #Q ON Q_Group = #Q.Q_Group
WHERE Q_Group <> '0'
ORDER BY Data_Field, Order_Nbr
-- Stop if no results found and return empty result set
IF (SELECT COUNT(*) FROM #t) = 0
BEGIN
SELECT order_nbr, question_txt, response FROM #t
RETURN
END
INSERT #i SELECT response_col FROM #t GROUP BY response_col
DECLARE #row_nbr int
DECLARE #last_row int
SET #row_nbr = 1
SET #last_row = (SELECT COUNT(*) FROM #i)
-- Iterate through each Data_Field found
WHILE #row_nbr <= #last_row
BEGIN
SET #response_col = (SELECT response_col FROM #i WHERE id = #row_nbr)
SET #sql = 'SELECT Order_Nbr, ' + #response_col + ' FROM Responses WHERE NullIf(' + #response_col + ','''') IS NOT NULL'
INSERT INTO #u
EXEC (#sql)
UPDATE #t
SET response = y.response
FROM #t AS x
INNER JOIN #u AS y ON x.order_nbr = y.order_nbr
SET #row_nbr = #row_nbr + 1
END
-- Remove results with no responses
DELETE FROM #t WHERE response IS NULL
SELECT order_nbr, question_txt, response FROM #t
RETURN

You will not be able to execute dynamic SQL from within a function but you could do this with a stored procedure and capture the output.
DECLARE #col_name VARCHAR(6), #param NVARCHAR(50), #myReturnValue VARCHAR(50)
SET #param = N'#result VARCHAR(50) OUTPUT'
DECLARE #sql VARCHAR(100)
SET #col_name = SELECT Data_Field FROM QUESTIONS WHERE Q_Group = 'R3'
AND Question_Desc = 'Do you have any allergies?'
SET #sql = 'SELECT #result = ' + #col_name + ' FROM RESPONSES WHERE Order_Nbr = 999'
EXEC sp_executesql #sql, #param, #result = #myReturnValue output
--manipulate value here
print #myReturnValue
You could also create a temp table and do an insert into from exec sp_executesql.

Related

Loop through a split string variable to insert rows in a stored procedure in SQL Server 2008

I am working on SQL Server 2008 to create a stored procedure that:
takes a string variable like this: '1,2,3'
splits the string using a table-valued function to get each value separately
and then inserts each value into a new row in a table
What I am trying to do is something like this:
WHILE (select vlaue FROM dbo.SplitString('1,2,3',',')) has rows
insert into TableName (col1,col2) values (col1Data, value)
I am having a hard time trying to find the right syntax for this.
I use this Table-valued function:
CREATE FUNCTION [dbo].[Split] (#sep char(1), #s varchar(512))
RETURNS table
AS
RETURN (
WITH Pieces(pn, start, stop) AS (
SELECT 1, 1, CHARINDEX(#sep, #s)
UNION ALL
SELECT pn + 1, stop + 1, CHARINDEX(#sep, #s, stop + 1)
FROM Pieces
WHERE stop > 0
)
SELECT pn,
SUBSTRING(#s, start, CASE WHEN stop > 0 THEN stop-start ELSE 512 END) AS s
FROM Pieces
)
GO
Which takes a string with a separator and returns a table with two columns the first returns a 1-based position and the second the element at that position in the string:
Usage:
SELECT * FROM dbo.Split(',', '1,2,3')
Returns:
pn s
1 1
2 2
3 3
To Insert results into a table:
INSERT INTO TableName (Col1)
SELECT S FROM dbo.Split(',', '1,2,3)
For your specific example change your syntax to be:
insert into TableName (col1,col2)
select col1Data, value FROM dbo.SplitString('1,2,3',',')
The typical INSERT INTO ... SELECT ... should do:
INSERT INTO TableName (col1,col2)
SELECT #col1Data,value FROM dbo.SplitString('1,2,3',','))
If someone else is looking for this, I was about to make a split function as several answers mentioned but noticed there's a built-in function that does this already.
string_split was added in MSSQL 2016.
INSERT INTO Project.FormDropdownAnswers (FkTableId, CreatedBy, CreatedDate)
SELECT 123, TRY_CAST(value AS INT), #username, getdate()
FROM string_split('44,45,46,47,55',',')
https://learn.microsoft.com/en-us/sql/t-sql/functions/string-split-transact-sql
CREATE TABLE tablename
(
id SMALLINT ,
value INT
)
INSERT INTO tablename ( id, value )
SELECT * FROM dbo.Split('1,2,3',',')
try this....
If need to use as variables there is 2 nice options:
Procedure MF_SPLIT
CREATE PROC [MF_SPLIT] (#ELS NVARCHAR(MAX)=NULL OUTPUT, #RET NVARCHAR(MAX)=NULL OUTPUT, #PROC NVARCHAR(MAX)=NULL) AS BEGIN
IF #ELS IS NULL BEGIN
PRINT ' #ELS
List of elements in string (OUTPUT)
#RET
Next return (OUTPUT)
#PROC
NULL = '','', content to do split
Example:
DECLARE #NAMES VARCHAR(100) = ''ERICK,DE,VATHAIRE''
DECLARE #N VARCHAR(100)
WHILE #NAMES IS NOT NULL BEGIN
EXEC MF_SPLIT #NAMES OUTPUT, #N OUTPUT
SELECT List = #NAMES, ActiveWord = #N
END'
RETURN
END
SET #PROC = ISNULL(#PROC, ',')
IF CHARINDEX(#PROC, #ELS) = 0 BEGIN
SELECT #RET = #ELS, #ELS = NULL
RETURN
END
SELECT
#RET = LEFT(#ELS, CHARINDEX(#PROC, #ELS) - 1)
, #ELS = STUFF(#ELS, 1, LEN(#RET) + 1, '')
END
Usage:
DECLARE #NAMES VARCHAR(100) = '1,2,3'
DECLARE #N VARCHAR(100)
WHILE #NAMES IS NOT NULL BEGIN
EXEC MF_SPLIT #NAMES OUTPUT, #N OUTPUT
SELECT List = #NAMES, ActiveWord = #N
END
Procedure MF_SPLIT_DO (Depends of MF_SPLIT), less sintax to use BUT the code will be in a string and use default variable "#X"
CREATE PROC MF_SPLIT_DO (#ARR NVARCHAR(MAX), #DO NVARCHAR(MAX)) AS BEGIN
--Less sintax
DECLARE #X NVARCHAR(MAX)
WHILE #ARR IS NOT NULL BEGIN
EXEC MF_SPLIT #ARR OUT, #X OUT
EXEC SP_EXECUTESQL #DO, N'#X NVARCHAR(MAX)', #X
END
END
Usage:
EXEC MF_SPLIT_DO '1,2,3', 'SELECT #X'

SSRS Pivot Expression Inside Stored Procedure with HashTemp Not Running

While Working With SSRS, Today, i got 2 Problems 1 is Still remain Unsolved and Im going to Post Another Freaking Problem :) Well, Problem is : I've an Stored Procedure, Which Create an #Temp and Finally Use that data with PIVOT Expression. And, Stored Procedure itself runs Fine inside SSMS and From Visual Basic 6.0 too, but While Using that Procedure from SSRS report it shows an error at the Pivot Expression. Following are the Screen Shots, Please Review and Suggest me an Idea.
Here is an Stored Procedure :
ALTER PROCEDURE [dbo].[S_NRB_9_8_REPORT](#SCRCODE AS VARCHAR(20),
#CUREDATE VARCHAR(10),
#DTNAME VARCHAR(50),
#BR_CODE VARCHAR(50),
#CENTRALIZED VARCHAR(3))
WITH RECOMPILE
AS BEGIN
SET NOCOUNT ON;
DECLARE #BRCODE VARCHAR(3)
DECLARE #DTBASE VARCHAR(50)
DECLARE #CAT_TYPE_CODE VARCHAR(50)
DECLARE #AC_TYPE_SUB_TYPE_NAME VARCHAR(200)
DECLARE #CODESTR VARCHAR (1000)
DECLARE #CODESTR1 VARCHAR (1000)
SET #BRCODE=''
SET #DTBASE=''
SET #AC_TYPE_SUB_TYPE_NAME=''
SET #CODESTR=''
SET #CODESTR1=''
SELECT TOP 1 #CAT_TYPE_CODE=CAT_TYPE_CODE FROM REPORT_CAT_TYPE_CODE WHERE SCREEN_CODE =#SCRCODE
IF #CAT_TYPE_CODE='' OR #CAT_TYPE_CODE IS NULL
RETURN
CREATE TABLE [dbo].[#TEMPACTYPE](
[BR_CODE] [varchar](3) NULL,
[CN] [varchar](50) NULL,
[CS] [varchar](50) NULL,
[BAL] decimal(18, 2) NULL,
[AC_TYPE_SUB_TYPE_NAME] [varchar](50) NULL
) ON [PRIMARY]
IF LEN(#BR_CODE)>0
EXEC('DECLARE CUR INSENSITIVE CURSOR FOR SELECT BR_CODE FROM '+#DTBASE+'.DBO.BRANCH B (NOLOCK) WHERE BR_CODE='''+#BR_CODE+''' AND INTEGRATED=''YES'' AND APPROVED=''YES'' ORDER BY BR_CODE')
ELSE
EXEC('DECLARE CUR INSENSITIVE CURSOR FOR SELECT BR_CODE FROM '+#DTBASE+'.DBO.BRANCH B (NOLOCK) WHERE INTEGRATED=''YES'' AND APPROVED=''YES'' ORDER BY BR_CODE')
OPEN CUR
FETCH NEXT FROM CUR INTO #BRCODE
While ##FETCH_STATUS = 0
Begin
IF #CENTRALIZED='YES'
SET #DTBASE = #DTNAME
ELSE
SET #DTBASE = Left(#DTNAME, 13) + #BRCODE
EXEC('INSERT INTO #TEMPACTYPE
SELECT '''+#BRCODE+''' AS BR_CODE,T1.CAT_NAME AS CN,T1.CODES AS CS,SUM(T1.C_BAL)AS BAL,T1.AC_TYPE_SUB_TYPE_NAME FROM
(SELECT C_BAL,ATST.AC_TYPE_SUB_TYPE_NAME,CD.CAT_NAME,CD.CODE_STRING AS CODES
FROM
(SELECT AC_GROUP_CODE,CUR_CODE,GL_CODE FROM '+#DTBASE+'.dbo.AC_GROUP_GL_MAP WHERE NAMED_AC_CODE =''0301'') MAP,
(SELECT AC_GROUP_CODE,CUR_CODE,AC_NO FROM '+#DTBASE+'.dbo.DEPOSIT_AC_MAST WHERE BR_CODE='''+#BRCODE+''') DAM,
(SELECT TRAN_DATE,AC_NO,GL_CODE,PRODUCT_CODE,SUM(CLS_BAL) AS C_BAL FROM '+#DTBASE+'.dbo.AC_BAL WHERE BR_CODE='''+#BRCODE+''' GROUP BY TRAN_DATE,AC_NO,GL_CODE,PRODUCT_CODE) WD,
(SELECT * FROM '+#DTBASE+'.dbo.CAT_CODING where BR_CODE='''+#BRCODE+''' AND CAT_TYPE_CODE ='''+#CAT_TYPE_CODE+''') AS CC,
(SELECT * FROM '+#DTBASE+'.dbo.AC_TYPE_SUB_TYPE) AS ATST,
(SELECT * FROM '+#DTBASE+'.dbo.AC_GROUP) AS AG,
(SELECT * FROM '+#DTBASE+'.dbo.CAT_DETL) AS CD
WHERE
DAM.AC_GROUP_CODE =MAP.AC_GROUP_CODE
AND DAM.CUR_CODE =MAP.CUR_CODE
AND WD.GL_CODE =MAP.GL_CODE
AND CC.ENTITY_NO=DAM.AC_NO
AND ATST.AC_TYPE_CODE=AG.AC_TYPE_CODE
AND ATST.AC_TYPE_SUB_TYPE_CODE=AG.AC_TYPE_SUB_TYPE_CODE
AND AG.AC_GROUP_CODE=DAM.AC_GROUP_CODE
AND CD.CAT_TYPE_CODE=CC.CAT_TYPE_CODE
AND CD.CAT_CODE=CC.CAT_CODE
AND CD.CAT_TYPE_CODE='''+#CAT_TYPE_CODE+'''
AND WD.TRAN_DATE = (SELECT MAX(TRAN_DATE) FROM '+#DTBASE+'.dbo.AC_BAL WHERE BR_CODE ='''+#BRCODE+''' AND AC_NO = DAM.AC_NO AND TRAN_DATE <='''+#CUREDATE+''' AND GL_CODE=MAP.GL_CODE)
AND DAM.AC_NO=WD.AC_NO
UNION ALL
SELECT 0,ATST.AC_TYPE_SUB_TYPE_NAME,CAT_NAME,CODE_STRING AS CODES FROM '+#DTBASE+'.dbo.CAT_DETL AS CD,'+#DTBASE+'.dbo.AC_TYPE_SUB_TYPE AS ATST
WHERE CAT_TYPE_CODE='''+#CAT_TYPE_CODE+''' AND CAT_CODE NOT IN (SELECT CAT_CODE FROM '+#DTBASE+'.dbo.CAT_CODING WHERE BR_CODE='''+#BRCODE+''' AND CAT_TYPE_CODE='''+#CAT_TYPE_CODE+''')
AND ATST.AC_TYPE_CODE=''03''
) T1
GROUP BY T1.AC_TYPE_SUB_TYPE_NAME,CAT_NAME,CODES
ORDER BY CODES
')
FETCH NEXT FROM CUR INTO #BRCODE
END
DEALLOCATE CUR
DECLARE CUR INSENSITIVE CURSOR FOR SELECT DISTINCT AC_TYPE_SUB_TYPE_NAME FROM #TEMPACTYPE
OPEN CUR
Fetch Next from CUR Into #AC_TYPE_SUB_TYPE_NAME
While ##FETCH_STATUS = 0
Begin
IF #CODESTR =''
BEGIN
SET #CODESTR = 'ISNULL(['+#AC_TYPE_SUB_TYPE_NAME+'],0) AS ['+#AC_TYPE_SUB_TYPE_NAME+']'
SET #CODESTR1 = '['+#AC_TYPE_SUB_TYPE_NAME+']'
END
ELSE
BEGIN
SET #CODESTR = #CODESTR+',ISNULL(['+#AC_TYPE_SUB_TYPE_NAME+'],0) AS ['+#AC_TYPE_SUB_TYPE_NAME+']'
SET #CODESTR1 = #CODESTR1+',['+#AC_TYPE_SUB_TYPE_NAME+']'
END
Fetch Next from CUR Into #AC_TYPE_SUB_TYPE_NAME
END
DEALLOCATE CUR
EXEC ('Select CS,CN,'+#CODESTR+',TOTAL
from (Select CN,CS,BAL,[AC_TYPE_SUB_TYPE_NAME] from #TEMPACTYPE) ps pivot (SUM([BAL])
for [AC_TYPE_SUB_TYPE_NAME] in ('+#CODESTR1+',TOTAL)) pvt
Order by CS')
DROP TABLE #TEMPACTYPE
END
GO
And, the Dataset Design Panel :
But, Stored Procedure Runs Well inside SSMS :
Im Using SSRS 2008 R2.
Please Help me out.
And, Thanks In Advance.
Try validating that you are passing the same parameter values between the report and SSMS. You can do this by clicking Edit Query and inputting the actual parameter values. If the Edit Query window returns proper results, then you are probably passing different values to the stored procedure.

how to use openrowset to execute a stored procedure with parameters

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

cursor logic in ssis

i have been strugling to convert the following t sql task into an automated ssis package.
i tried implementing using for loop conntainer but while creating the looping logic i am stucking off. i really appreciate of some one could help me out with logic
here is the t- sql code
-- SCRIPT TO BULK IMPORT MATERNAL HLA & INSERT CORD NIMA
IF OBJECT_ID('tempdb..#maternal_hla_from_solar') IS NOT NULL
BEGIN
drop table #maternal_hla_from_solar
END
CREATE TABLE #maternal_hla_from_solar(
[donor_id] [int] NOT NULL,
[antigen_id] [int] NOT NULL
)
-- bulk upload maternal HLA from file
BULK
INSERT #maternal_hla_from_solar
FROM 'C:\Users\zabeenp\Documents\SQL\populate_db\data\20111212_maternal_hla.txt'
WITH
(
FIRSTROW = 2,
MAXERRORS = 0,
FIELDTERMINATOR = '\t',
ROWTERMINATOR = '\n'
)
-- declare variables
DECLARE #donor_id int
DECLARE #maternal_hla varchar(5000)
DECLARE #definitive_type_date date = GETDATE()
DECLARE #modified_on datetime2(7) = GETDATE()
-- Cursor to process each row from #maternal_hla_from_solar
DECLARE c_insertCordNima CURSOR FAST_FORWARD
FOR select DISTINCT donor_id from #maternal_hla_from_solar -- important to use DISTINCT here
OPEN c_insertCordNima
FETCH NEXT FROM c_insertCordNima INTO #donor_id
WHILE ##FETCH_STATUS = 0
BEGIN
SET #maternal_hla = '' -- important to wipe string each time
-- concatenare maternal antigen_ids into one string
SELECT #maternal_hla = COALESCE(#maternal_hla + ',', '') + CONVERT(VARCHAR(10),antigen_id)
FROM #maternal_hla_from_solar
where donor_id = #donor_id
-- remove first comma
SET #maternal_hla = (select right(#maternal_hla,len(#maternal_hla)-1))
-- exec insertCordNIMA SP
EXECUTE insertCordNIMA
#donor_id
,#maternal_hla
,#definitive_type_date
,#modified_on
FETCH NEXT FROM c_insertCordNima INTO #donor_id
END
CLOSE c_insertCordNima
DEALLOCATE c_insertCordNima
maybe try to rewrite the cursor using a Recursive CTE?
http://msdn.microsoft.com/en-us/library/ms186243.aspx

Dynamic insert into variable table statement SQL Server

I have a variable table:
DECLARE #A_Table TABLE(ID INT, att1 VARCHAR(100), att2 nvarchar(200))
I want to make dynamic sql, so I insert into this table some data (all inside a loop):
WHILE (#i <= 100) BEGIN
SELECT #other_att = NAME FROM #other_Table where ID = #i;
SET #sql = 'INSERT ' + #A_Table+ '(ID,att1,att2) SELECT '+CAST(#i AS VARCHAR)+' , '''+ #other_att+''', SUM('+ #other_att') FROM '+ #EVEN_OTHER_Table;
EXEC (#sql);
END
sql every time would look like:
INSERT INTO #A_Table SELECT 1 , 'subject', SUM(subject)
INSERT INTO #A_Table SELECT 2 , 'age', SUM(age)
INSERT INTO #A_Table SELECT 3 , 'sex', SUM(sex)....
AND after executing this :
SO I will get:
#A_Table:
id att1 att2
1 subject 4.3
2 age 4.5
3 sex 4.1
but I get an error:
Msg 137, Level 16, State 1, Line 48
Must declare the scalar variable "#A_Table".
SO what is it the syntax to insert dynamically into a variable table?
Ok I have understood it.
You could use the INSERT ... EXEC syntax to insert the data returned by the dynamic SELECT. Of course, you would then need to remove the INSERT part from the dynamic statement.
WHILE (#i <= 100) BEGIN
SELECT #other_att = NAME FROM #other_Table where ID = #i;
SET #sql = 'SELECT '+CAST(#i AS VARCHAR)+' , ''' + #other_att+''', SUM('+ #other_att + ') FROM '+ #EVEN_OTHER_Table;
INSERT INTO #A_Table (ID,att1,att2)
EXEC (#sql);
END
You have a table variable, not a variable that contains the table name.
So you would need the following.
WHILE (#i <= 100) BEGIN
SELECT #other_att = NAME FROM #other_Table where ID = #i;
SET #sql = 'INSERT INTO #A_Table (ID,att1,att2) SELECT '+CAST(#i AS VARCHAR)+' , '''+ #other_att+''', SUM('+ #other_att') FROM #EVEN_OTHER_Table';
EXEC (#sql);
END
You would also need to declare the table variable as a statement inside the #sql variable, and execute your declare table and inserts together, or use a local/global temporary table.
With a local temporary table (stored in the tempdb) you could do something like this.
CREATE TABLE #testtbl (ID INT);
EXEC ('INSERT INTO #testtbl VALUES (1)');
SELECT * FROM #testtbl
DROP TABLE #testtbl
Some good info about temporary tables in BOL
http://msdn.microsoft.com/en-us/library/ms174979.aspx - quite far down the page
And the table type.
http://msdn.microsoft.com/en-us/library/ms175010.aspx
Your EXEC statement occurs in a different context and is therefore unaware of any variables created in your original context.
To create dynamic insert query it is really a task, I also struggle to find it ,finally I have tried in the following way and it's successfully working. Please find the code below.
CREATE PROCEDURE [dbo].[InsertTodaysData] (#tbl varchar(50),#Days int,
#MDate varchar(50), #EValue varchar(50), #Speed varchar(50),
#Totalreturn varchar(50),#Closingv varchar(50), #TotalReturnV varchar(50))
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
DECLARE #SQLQuery varchar(2000)
-- Insert statements for procedure here
set #SQLQuery = 'INSERT INTO '+#tbl+' (ID,MDate,EValue,Speed,TotalReturnRatio,ClosingValue,
TotalReturnValue) VALUES ('+#Days+','''+#MDate+''', '+#EValue+', '+#Speed+',
'+#Totalreturn+', '+#Closingv+', '+#TotalReturnV+')'
EXECUTE(#SQLQuery)
END
Hope this will help you..