Unable to Create the Complete Dynamic Query using NVARCHAR(Max) - sql

I am using NVARCHAR(MAX) to create a dynamic query.Since NVARCHAR uses 2 bytes per character, Approximately 1 billion characters can include in NVARCHAR(MAX) variable (Link Reference) .
I tried by executing stored procedure in SQL Server itself, then executing the stored procedure through the application.
Both situation dynamic query is not exceeding those character length. But only part of the Dynamic query is get executed.Because of that stored procedure throw errors to the application.
Am I missing any code ?
USE [MyDemoDB]
GO
ALTER PROCEDURE [dbo].[sp_Apply]
(
#scenarioId INT,
#userId INT,
#bookId INT
)
AS
DECLARE #BucketId INT
DECLARE #HierarchyId NVARCHAR(10)
DECLARE #Year INT
DECLARE #Month INT
DECLARE #PlanningSeason NVARCHAR(20)
DECLARE #StructureId INT = 9
DECLARE #AllocStructureId INT = 11
DECLARE #UpdatedUser INT = 2
DECLARE #InsertOne NVARCHAR(MAX)=''
DECLARE #AreaSchema NVARCHAR(40)
DECLARE #AreaCode NVARCHAR(20)
DECLARE #EmptyValue NVARCHAR(20)
SET #AreaCode = ''
SET #AreaSchema = '[dbo]'
SET #InsertOne = '
DECLARE #FGSupplySeqId INT
DECLARE #FGSupplyId NVARCHAR(10)
DECLARE #PlannedQty DECIMAL(18,2)
DECLARE #ConfirmdQty DECIMAL(18,2)
DECLARE #Year INT
DECLARE #Month INT
DECLARE #Season NVARCHAR(20)
DECLARE #MerchantId NVARCHAR(50)
DECLARE #UpdatedUser INT
DECLARE #HierarchyId NVARCHAR(10)
DECLARE #BucketId INT
DECLARE #ProductNo NVARCHAR(100)
DECLARE #LocationNo NVARCHAR(100)
SET #BucketId = '+ CAST(#BucketId AS VARCHAR) + '
SET #UpdatedUser = '+ CAST(#userId AS VARCHAR) + '
IF #BucketId = 1
BEGIN
DECLARE Supplys
CURSOR FOR
SELECT [FGSupplySeqId],[FGSupplyId] FROM ' + #AreaSchema + '.[FGSupply]
WHERE PlanningScenarioId ='+ CONVERT(VARCHAR(10),#scenarioId)+ '
OPEN Supplys
FETCH NEXT
FROM Supplys
INTO #FGSupplySeqId,#FGSupplyId
WHILE ##FETCH_STATUS = 0
BEGIN
DECLARE Allocations
CURSOR FOR
SELECT #FGSupplyId,FGHierarchyId,MerchantNo,PlannedQty,ConfirmedQty,Year,Season,ProductNo,LocationNo
FROM '+ #AreaSchema +'.[FGAllocation]
WHERE FGSupplySeqId = #FGSupplySeqId
OPEN Allocations
FETCH NEXT
FROM Allocations
INTO #FGSupplyId,#HierarchyId,#MerchantId,#PlannedQty,#ConfirmdQty,#Year,#Season,#ProductNo,#LocationNo
WHILE ##FETCH_STATUS = 0
BEGIN
DECLARE #FGAllocationId NVARCHAR(10)
DECLARE #AllocStatus INT
SET #FGAllocationId = ''E''
SET #AllocStatus= 0
SELECT #FGAllocationId = FGAllocationId,#AllocStatus=Status
FROM ' + #AreaSchema+'.[SN_PLANNING_FGAllocation]
WHERE [HierarchyId]=#HierarchyId AND [MerchantNo]=#MerchantId AND YEAR = #Year AND [Month] IS NULL
IF #FGAllocationId = ''E''
BEGIN
-- IF #AllocStatus <> 5
INSERT INTO'+ #AreaSchema+'.[SN_PLANNING_FGAllocation]
(FinishedGoodSupplyId,FGHierarchyId,MerchantNo,PlannedQty,Year,Season,Status,IsActive,CreatedBy,UpdatedBy,CreatedOn,UpdatedOn,ProductNo,LocationNo)
VALUES(#FGSupplyId,#HierarchyId,#MerchantId,#PlannedQty,#Year,#Season,0,1,#UpdatedUser,#UpdatedUser,GETDATE(),GETDATE(),#ProductNo,#LocationNo)
END
ELSE
BEGIN
-- IF #AllocStatus <> 5
UPDATE ' + #AreaSchema + '.[SN_PLANNING_FGAllocation]
SET PlannedQty = #PlannedQty ,ConfirmedQty=#ConfirmdQty,UpdatedBy=#UpdatedUser, UpdatedOn=GETDATE()
WHERE FGAllocationId = #FGAllocationId
END
FETCH NEXT
FROM Allocations
INTO #FGSupplyId,#HierarchyId,#MerchantId,#PlannedQty,#ConfirmdQty,#Year,#Season,#ProductNo,#LocationNo
END
CLOSE Allocations
DEALLOCATE Allocations
FETCH NEXT
FROM Supplys
INTO #FGSupplySeqId,#FGSupplyId
END
CLOSE Supplys
DEALLOCATE Supplys
END
IF #BucketId = 2
BEGIN
DECLARE Supplys
CURSOR FOR
SELECT [FGSupplySeqId],[FGSupplyId] FROM ' + #AreaSchema + '.[FGSupply]
WHERE PlanningScenarioId ='+ CONVERT(VARCHAR(10),#scenarioId)+ 'AND Month IS NOT NULL
OPEN Supplys
FETCH NEXT
FROM Supplys
INTO #FGSupplySeqId,#FGSupplyId
WHILE ##FETCH_STATUS = 0
BEGIN
DECLARE Allocations
CURSOR FOR
SELECT #FGSupplyId,FGHierarchyId,MerchantNo,PlannedQty,ConfirmedQty,Year, Month,Season,#ProductNo,#LocationNo
FROM '+ #AreaSchema +'.[FGAllocation]
WHERE FGSupplySeqId = #FGSupplySeqId AND Month IS NOT NULL
OPEN Allocations
FETCH NEXT
FROM Allocations
INTO #FGSupplyId,#HierarchyId,#MerchantId,#PlannedQty,#ConfirmdQty,#Year,#Month,#Season,#ProductNo,#LocationNo
WHILE ##FETCH_STATUS = 0
BEGIN
DECLARE #FGAllocationId1 NVARCHAR(10)
SET #FGAllocationId1 = ''E''
SELECT #FGAllocationId1 = FGAllocationId,#AllocStatus=Status
FROM ' + #AreaSchema+'.[SN_PLANNING_FGAllocation]
WHERE [HierarchyId]=#HierarchyId AND [MerchantNo]=#MerchantId AND YEAR = #Year AND [Month] = #Month
IF #FGAllocationId1 = ''E''
BEGIN
-- IF #AllocStatus <> 5
INSERT INTO'+ #AreaSchema+'.[SN_PLANNING_FGAllocation]
(FGSupplyId,FGHierarchyId,MerchantNo,PlannedQty,Year,Month,Season,Status,IsActive,CreatedBy,UpdatedBy,CreatedOn,UpdatedOn,ProductNo,LocationNo)
VALUES(#FGSupplyId,#HierarchyId,#MerchantId,#PlannedQty,#Year,#Month,#Season,0,1,#UpdatedUser,#UpdatedUser,GETDATE(),GETDATE(),#ProductNo,#LocationNo)
END
ELSE
BEGIN
-- IF #AllocStatus <> 5
UPDATE ' + #AreaSchema + '.[SN_PLANNING_FGAllocation]
SET PlannedQty = #PlannedQty ,ConfirmedQty=#ConfirmdQty,UpdatedBy=#UpdatedUser, UpdatedOn=GETDATE()
WHERE FGAllocationId = #FGAllocationId1
END
FETCH NEXT
FROM Allocations
INTO #FGSupplyId,#HierarchyId,#MerchantId,#PlannedQty,#ConfirmdQty,#Year,#Month,#Season,#ProductNo,#LocationNo
END
CLOSE Allocations
DEALLOCATE Allocations
FETCH NEXT
FROM Supplys
INTO #FGSupplySeqId,#FGSupplyId
END
CLOSE Supplys
DEALLOCATE Supplys
END'
print #InsertOne
EXEC(#InsertOne)

Yes, you may be facing the issue because of nvarchar limit is 4000 characters.
I also face this issue and resolved by concatenate the string and then execute.
If you select or print it only show 4000 character, but if you concatenate or append the string it must append (till 8000 character). So don't bother about this, you do not print or select just append and execute and its definitely work.
In this link this is explain.
declare #sql Nvarchar(max),
#a nvarchar(max),
#b nvarchar(max);
select #sql =N'', #a = N'a', #b = N'b';
select #sql = #sql +replicate(#a,4000) + replicate(#b, 6000);
select len(#sql)
There is one rule for this :-
SET #dynamicSQL = [concatenate various unicode strings and nvarchar
variables totalling over 4000 characters] -- MAKE SURE AT LEAST ONE OF
THE UNICODE STRINGS IS NVARCHAR(MAX), YOU CAN CAST ANY ONE ARGUMENT.
You can check this link also.
https://dba.stackexchange.com/questions/18483/varcharmax-field-cutting-off-data-after-8000-characters-sql-server-2008
Updated
I show your entire code and want to explain some things.
First of all, why you want dynamic query. Code shows that you can do it without dynamic query and also there is so much nested cursor (try to ignore it with simple query)
Still if you want to go, then I remove you extra code (I don't think that remove space will work, I had 4 union query and its very huge length and its work with this strategy after verify each part in separate window)
a.Here is another option before you read below. rather than define parameter in query, you can pass this parameter too.
begin tran
create table table1 ( id int, value varchar(10) )
insert into table1 values( 1,'001')
insert into table1 values(2, '002')
insert into table1 values( 3,'003')
insert into table1 values( 4,'004')
declare #sql nvarchar(max) , #temp nvarchar(50) = '1,2,3', #tempIntSingleValue nvarchar(50) = '2'
select * from table1
set #sql = 'select * from table1 where id in ( ' + #temp + ')'
print #sql
exec sp_executesql #sql
set #sql = 'select * from table1 where id in ( #tempInner)'
print #sql
exec sp_executesql #sql , N'#tempInner int', #tempInner = #tempIntSingleValue
rollback
b. you used same parameter in your dynamic query. so I think issue with you have to give either default value or assign value at run-time. so while concatenating your string not become null. See this example below. I am define all character to '' and int to numeric value and at last print which print something. If we not define it never print blank due to concatenate set null value.
declare #scenarioId INT = 1 ,
#userId INT = 5,
#bookId INT = 1
DECLARE #BucketId INT = 0
DECLARE #HierarchyId NVARCHAR(10)
DECLARE #Year INT
DECLARE #Month INT
DECLARE #PlanningSeason NVARCHAR(20)
DECLARE #StructureId INT = 9
DECLARE #AllocStructureId INT = 11
DECLARE #UpdatedUser INT = 2
DECLARE #InsertOne NVARCHAR(MAX) =''
DECLARE #AreaSchema NVARCHAR(40)
DECLARE #AreaCode NVARCHAR(20)
DECLARE #EmptyValue NVARCHAR(20)
SET #AreaCode = ''
SET #AreaSchema = '[dbo]'
SET #InsertOne =
'DECLARE #FGSupplySeqId INT = 5
DECLARE #FGSupplyId NVARCHAR(10) = ''''
DECLARE #PlannedQty DECIMAL(18,2) = ''''
DECLARE #ConfirmdQty DECIMAL(18,2) = ''''
DECLARE #Year INT = 2015
DECLARE #Month INT = 7
DECLARE #Season NVARCHAR(20) = ''''
DECLARE #MerchantId NVARCHAR(50) = ''''
DECLARE #UpdatedUser INT
DECLARE #HierarchyId NVARCHAR(10) = ''''
DECLARE #BucketId INT = 0
DECLARE #ProductNo NVARCHAR(100)= ''''
DECLARE #LocationNo NVARCHAR(100)
SET #BucketId = '+ CAST(#BucketId AS VARCHAR) + '
SET #UpdatedUser = '+ CAST(#userId AS VARCHAR) + '
IF #BucketId = 1
BEGIN
DECLARE Supplys
CURSOR FOR
SELECT [FGSupplySeqId],[FGSupplyId] FROM ' + #AreaSchema + '.[FGSupply]
WHERE PlanningScenarioId ='+ CONVERT(VARCHAR(10),#scenarioId)+ '
OPEN Supplys
FETCH NEXT
FROM Supplys
INTO #FGSupplySeqId,#FGSupplyId
WHILE ##FETCH_STATUS = 0
BEGIN
DECLARE Allocations
CURSOR FOR
SELECT #FGSupplyId,FGHierarchyId,MerchantNo,PlannedQty,ConfirmedQty,Year,Season,ProductNo,LocationNo
FROM '+ #AreaSchema +'.[FGAllocation]
WHERE FGSupplySeqId = #FGSupplySeqId
OPEN Allocations
FETCH NEXT
FROM Allocations
INTO #FGSupplyId,#HierarchyId,#MerchantId,#PlannedQty,#ConfirmdQty,#Year,#Season,#ProductNo,#LocationNo
WHILE ##FETCH_STATUS = 0
BEGIN
DECLARE #FGAllocationId NVARCHAR(10)
DECLARE #AllocStatus INT
SET #FGAllocationId = ''E''
SET #AllocStatus= 0
SELECT #FGAllocationId = FGAllocationId,#AllocStatus=Status
FROM ' + #AreaSchema+'.[SN_PLANNING_FGAllocation]
WHERE [HierarchyId]=#HierarchyId AND [MerchantNo]=#MerchantId AND YEAR = #Year AND [Month] IS NULL
IF #FGAllocationId = ''E''
BEGIN
-- IF #AllocStatus <> 5
INSERT INTO'+ #AreaSchema+'.[SN_PLANNING_FGAllocation]
(FinishedGoodSupplyId,FGHierarchyId,MerchantNo,PlannedQty,Year,Season,Status,IsActive,CreatedBy,UpdatedBy,CreatedOn,UpdatedOn,ProductNo,LocationNo)
VALUES(#FGSupplyId,#HierarchyId,#MerchantId,#PlannedQty,#Year,#Season,0,1,#UpdatedUser,#UpdatedUser,GETDATE(),GETDATE(),#ProductNo,#LocationNo)
END
ELSE
BEGIN
-- IF #AllocStatus <> 5
UPDATE ' + #AreaSchema + '.[SN_PLANNING_FGAllocation]
SET PlannedQty = #PlannedQty ,ConfirmedQty=#ConfirmdQty,UpdatedBy=#UpdatedUser, UpdatedOn=GETDATE()
WHERE FGAllocationId = #FGAllocationId
END
FETCH NEXT
FROM Allocations
INTO #FGSupplyId,#HierarchyId,#MerchantId,#PlannedQty,#ConfirmdQty,#Year,#Season,#ProductNo,#LocationNo
END
CLOSE Allocations
DEALLOCATE Allocations
FETCH NEXT
FROM Supplys
INTO #FGSupplySeqId,#FGSupplyId
END
CLOSE Supplys
DEALLOCATE Supplys
END
IF #BucketId = 2
BEGIN
DECLARE Supplys
CURSOR FOR
SELECT [FGSupplySeqId],[FGSupplyId] FROM ' + #AreaSchema + '.[FGSupply]
WHERE PlanningScenarioId ='+ CONVERT(VARCHAR(10),#scenarioId)+ 'AND Month IS NOT NULL
OPEN Supplys
FETCH NEXT
FROM Supplys
INTO #FGSupplySeqId,#FGSupplyId
WHILE ##FETCH_STATUS = 0
BEGIN
DECLARE Allocations
CURSOR FOR
SELECT #FGSupplyId,FGHierarchyId,MerchantNo,PlannedQty,ConfirmedQty,Year, Month,Season,#ProductNo,#LocationNo
FROM '+ #AreaSchema +'.[FGAllocation]
WHERE FGSupplySeqId = #FGSupplySeqId AND Month IS NOT NULL
OPEN Allocations
FETCH NEXT
FROM Allocations
INTO #FGSupplyId,#HierarchyId,#MerchantId,#PlannedQty,#ConfirmdQty,#Year,#Month,#Season,#ProductNo,#LocationNo
WHILE ##FETCH_STATUS = 0
BEGIN
DECLARE #FGAllocationId1 NVARCHAR(10)
SET #FGAllocationId1 = ''E''
SELECT #FGAllocationId1 = FGAllocationId,#AllocStatus=Status
FROM ' + #AreaSchema+'.[SN_PLANNING_FGAllocation]
WHERE [HierarchyId]=#HierarchyId AND [MerchantNo]=#MerchantId AND YEAR = #Year AND [Month] = #Month
IF #FGAllocationId1 = ''E''
BEGIN
-- IF #AllocStatus <> 5
INSERT INTO'+ #AreaSchema+'.[SN_PLANNING_FGAllocation]
(FGSupplyId,FGHierarchyId,MerchantNo,PlannedQty,Year,Month,Season,Status,IsActive,CreatedBy,UpdatedBy,CreatedOn,UpdatedOn,ProductNo,LocationNo)
VALUES(#FGSupplyId,#HierarchyId,#MerchantId,#PlannedQty,#Year,#Month,#Season,0,1,#UpdatedUser,#UpdatedUser,GETDATE(),GETDATE(),#ProductNo,#LocationNo)
END
ELSE
BEGIN
-- IF #AllocStatus <> 5
UPDATE ' + #AreaSchema + '.[SN_PLANNING_FGAllocation]
SET PlannedQty = #PlannedQty ,ConfirmedQty=#ConfirmdQty,UpdatedBy=#UpdatedUser, UpdatedOn=GETDATE()
WHERE FGAllocationId = #FGAllocationId1
END
FETCH NEXT
FROM Allocations
INTO #FGSupplyId,#HierarchyId,#MerchantId,#PlannedQty,#ConfirmdQty,#Year,#Month,#Season,#ProductNo,#LocationNo
END
CLOSE Allocations
DEALLOCATE Allocations
FETCH NEXT
FROM Supplys
INTO #FGSupplySeqId,#FGSupplyId
END
CLOSE Supplys
DEALLOCATE Supplys
END'
print #InsertOne

Make sure your variable don't contain quotes or double quote them.
declare #value nvarchar(100) = 'abcd''efgh'
declare #sql nvarchar(max)
-- tons of QUOTE !!!
Set #sql = N'select ''' + REPLACE(#value, '''', '''''') + '''';
print #sql
exec sp_executesql #sql
Put brackets around your object names and at least one space between into and DB:
INSERT INTO'+ #AreaSchema+'.[SN_PLANNING_FGAllocation]
-- space is missing
or you can use the QUOTENAME function QUOTENAME(#AreaSchema)
Use N'' and NVARCHAR(...) or '' and VARCHAR() but don't mix
You declare everything as NVARCHAR and then concatenate it with ''. It should be N''. You also convert/cast everything as VARCHAR. It should be NVARCHAR(...).
Dynamic SQL use a NVARCHAR string.
Make sure variable are set or have a default value
SET #BucketId = '+ CAST(#BucketId AS nVARCHAR) + '
This will return NULL because #BucketId is not set in your stored procedure. Either use a ISNULL, set it or give it a default value
You should use EXEC sp_executesql and declare variables when they are used as such
https://msdn.microsoft.com/fr-fr/library/ms188001(v=sql.120).aspx
EXEC sp_executesql #yourquery, N'#UserID int, ...', #userID = #UserId ...
Keep concatenation only when it is needed (dynamic object names)
Finally
Before trying to execute it, make sure your print output the correct query (print only show the 1st 4000 characters). If the query is incomplete, it probably means that your have an error in the code near the line where it stop.
I tried your proc and it returns nothing (NULL) the way it is unless I first init all the variables. There are also truncations because you do not use N''

Related

The number of variables declared in the INTO list must match that of selected columns one select one into

This is a pretty straightforward error, but I can't figure out why I am getting it. I have one column selected in my declare (TABLE_NAME) and am fetching into one variable (#cTableName). What gives?
CREATE PROCEDURE [dbo].[updateNumbers_ArchiveDB]
(
#accountNumber varchar(50),
#padding varchar(50),
#proc_dateStart datetime,
#proc_dateEnd datetime
)
AS
DECLARE #cTableName varchar(50)
DECLARE CursorYearlyTables CURSOR FOR
SELECT TABLE_NAME
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME like 'Archive[12]%' and len(TABLE_NAME) = 14
ORDER BY TABLE_NAME;
-- =============================================
-- Open the cursor and iterate over the monthlies
-- =============================================
OPEN CursorYearlyTables
fetch next from CursorYearlyTables into #cTableName
while (##fetch_status <> -1)
BEGIN
SET NOCOUNT ON;
declare #q varchar(1000);
set #q = 'Update' + #cTableName +
'SET LogicalAccount = #padding + #accountNumber' +
'WHERE ProcessDate BETWEEN CAST(#proc_dateStart AS DATE) AND CAST(#proc_dateEnd AS DATE)'
exec(#q)
fetch next from CursorYearlyTables into #cTableName
END
close CursorYearlyTables;
DEALLOCATE CursorYearlyTables;
Could you try it with these lines in the cursor
declare #q nvarchar(max);
set #q = 'Update ' + #cTableName +
'SET LogicalAccount = '+#padding + #accountNumber +
'WHERE ProcessDate BETWEEN CAST('''+CONVERT(VARCHAR(20),#proc_dateStart)+''' AS DATE) AND CAST('''+CONVERT(VARCHAR(20),#proc_dateEnd)+''' AS DATE)'
exec sp_executesql #q
to account for SQL_Injection DavidG commented:
declare
#q nvarchar(max) = 'update '+#cTableName+' SET LogicalAccount = #a where ProcessDate BETWEEN CAST(#b AS DATE) AND CAST(#c AS DATE))',
#param1 nvarchar(100) = #padding+ #accountNumber,
#ParamDefinition nvarchar(500) = N'#a varchar(100), #b datetime, #c datetime'
exec sp_executesql #q, #ParamDefinition,#a = #param1,#b = #proc_dateStart, #cTableName = #proc_dateEnd
Please use CONVERT function
CAST('''+CONVERT(VARCHAR(108),#proc_dateStart)+''' AS DATE) AND CAST('''+CONVERT(VARCHAR(108),#proc_dateEnd)+''' AS DATE)'

SQL cursor variable can not use in conditions

any idea why my #ProductNumber cursor variable is not working if used in dynamic statement? It says "Must declare scalar variable". But this is a cursor variable. But when I used it not dynamic, it works. Thanks.
DECLARE #TargetDB NVARCHAR(50)
DECLARE #SourceDB NVARCHAR(50)
DECLARE #DateEffectiveFrom datetime
DECLARE #InsertRecords NVARCHAR(1000)
SET #TargetDB = 'MySSISDb'
SET #SourceDB = 'MySSISDb2'
SET #DateEffectiveFrom = '2013-12-29'
Declare #ProductNumber INT;
DECLARE #SqlDb NVARCHAR(Max)
DECLARE Cur1 CURSOR FOR SELECT CAST(#SqlDb AS NVARCHAR(MAX))
SET #SqlDb = 'SELECT ProductNumber From '+#SourceDB+'.dbo.Item (NOLOCK)
WHERE NOT EXISTS (SELECT 1 FROM '+#TargetDB+'.dbo.Item2
WHERE ProductNumber = '+#SourceDB+'.dbo.Item.ProductNumber)'
EXEC sp_executesql #SqlDb
OPEN Cur1
FETCH NEXT FROM Cur1 INTO #ProductNumber;
WHILE ##FETCH_STATUS = 0
BEGIN
SET #InsertRecords = 'INSERT INTO ' + #TargetDB + '.dbo.Item2(
ProductNumber, ProductName, ListPrice, BirthDate)
SELECT ProductNumber, ProductName,
ListPrice, ''' + CONVERT(nvarchar(25),#DateEffectiveFrom,120) + '''
FROM ' + #SourceDB + '.dbo.Item
WHERE ' + #SourceDB + '.dbo.Item.ProductNumber = #ProductNumber'
--WHERE ' + #SourceDB + '.dbo.Item.ProductNumber = #ProductNumber
--(this is where the problem)
EXEC sp_executesql #InsetRecords
FETCH NEXT FROM Cur1 INTO #ProductNumber;
END
CLOSE Cur1;
DEALLOCATE Cur1;
Shift the declaration of your cursor into the SQLDb variable. In SQL Server, at least, the cursor designation "Cur1" is accessible after the execution of #SQLDb. Also, I've moved the use of #ProductNumber to outside the literal string and fixed a typo on your second EXEC statement within the cursor while loop (#InsetRecords to #InsertRecords).
DECLARE #TargetDB NVARCHAR(50)
DECLARE #SourceDB NVARCHAR(50)
DECLARE #DateEffectiveFrom datetime
DECLARE #InsertRecords NVARCHAR(1000)
SET #TargetDB = 'MySSISDb'
SET #SourceDB = 'MySSISDb2'
SET #DateEffectiveFrom = '2013-12-29'
Declare #ProductNumber INT;
DECLARE #SqlDb NVARCHAR(Max)
SET #SqlDb = '
DECLARE Cur1 CURSOR FOR
SELECT ProductNumber
From '+#SourceDB+'.dbo.Item (NOLOCK)
WHERE NOT EXISTS (
SELECT 1
FROM '+#TargetDB+'.dbo.Item2
WHERE ProductNumber = '+#SourceDB+'.dbo.Item.ProductNumber)'
EXEC sp_executesql #SqlDb
OPEN Cur1
FETCH NEXT FROM Cur1 INTO #ProductNumber;
WHILE ##FETCH_STATUS = 0
BEGIN
SET #InsertRecords = 'INSERT INTO ' + #TargetDB + '.dbo.Item2(
ProductNumber, ProductName, ListPrice, BirthDate)
SELECT ProductNumber, ProductName,
ListPrice, ''' + CONVERT(nvarchar(25),#DateEffectiveFrom,120) + '''
FROM ' + #SourceDB + '.dbo.Item
WHERE ' + #SourceDB + '.dbo.Item.ProductNumber = ' + CONVERT(nvarchar(max), #ProductNumber)
EXEC sp_executesql #InsertRecords
FETCH NEXT FROM Cur1 INTO #ProductNumber;
END
CLOSE Cur1;
DEALLOCATE Cur1;

How to Loop table creation

I have the following code which works fine for one table but I am trying to figure out how to make it loop.
DECLARE #sql NVARCHAR(2000)
DECLARE #table VARCHAR(100)
DECLARE #command NVARCHAR(1000)
SELECT #table = ( VV.SRC_CD )
FROM VV
SET #sql = 'SELECT [CD],[SRC_CD],[SRC_CD_DESC],[DSC],[REFRESH_DT],[GEN_DSC] = CAST(null as VARCHAR(50)) INTO dbo.vv_' + #table
+
' FROM [vv] A WHERE A.SRC_CD <> ''GEN'' AND A.DSC <> ''NO DATA'' AND A.DSC <> ''(BLANK) NO'' AND A.src_cd = '''
+ #table + ''''
EXEC Sp_executesql
#stmt = #sql
The code that populates the #table variable returns one row. What I am trying to do is get this procedure to loop one time for each distinct value in the table for that row. The distinct clause doesn't work here and I have tried a basic table array with no luck.
Do I need to modify this to use a cursor?
It sounds like you're in need of a cursor, something like:
DECLARE #Iterator NVARCHAR(100)
,#sql NVARCHAR(MAX)
DECLARE xyz CURSOR
FOR
--Select stuff to iterate over
SELECT DISTINCT SRC_CD
FROM w
OPEN xyz
FETCH NEXT FROM xyz
INTO #Iterator
WHILE ##FETCH_STATUS = 0
BEGIN
--Do stuff
SET #sql = 'SELECT [CD],[SRC_CD],[SRC_CD_DESC],[DSC],[REFRESH_DT],[GEN_DSC] = CAST(null as VARCHAR(50))
INTO dbo.vv_' + #Iterator +'
FROM [vv] A
WHERE A.SRC_CD <> ''GEN''
AND A.DSC <> ''NO DATA''
AND A.DSC <> ''(BLANK) NO''
AND A.src_cd = ''' + #Iterator + ''''
PRINT (#sql)
FETCH NEXT FROM xyz
INTO #Iterator
END
CLOSE xyz
DEALLOCATE xyz
GO
I left PRINT in there so you can ensure the output is as desired before executing.

how to use print statement when you have more than 8000 characters

I have a procedure and the code looks like this:
ALTER PROCEDURE [dbo].[usp_Gen_Proc]
(#ID INT )
AS
Begin
IF OBJECT_ID('tempdb..#procedure') IS NOT NULL
DROP TABLE #procedure
DECLARE #Name VARCHAR(100)
DECLARE #SQL VARCHAR(MAX)
DECLARE #Script VARCHAR(MAX),
#DB VARCHAR(100),
#Schema VARCHAR(100),
#Proc_Name VARCHAR(max),
#BR CHAR(2)
SET #BR = CHAR(10)+ CHAR(13)
SET NOCOUNT ON
SELECT #Name= [Procedure_Name] FROM dbo.datsource
WHERE [ID] = #ID
SELECT #Proc_Name = PARSENAME(#Name, 1) ,
#Schema = PARSENAME(#Name, 2) ,
#DB = PARSENAME(#Name, 3)
CREATE TABLE #procedure ( script VARCHAR(MAX) )
EXEC('INSERT INTO #procedure(script)
SELECT definition FROM '+#DB+'.sys.all_sql_modules sq
WHERE sq.object_id = (SELECT object_id FROM '+#DB+'.sys.objects
WHERE type = ''P'' AND name = '''+#Proc_Name+''' ) ')
SET #Script = ' Use ' +#BR +#DB + #BR+ ' Go' +#BR
SELECT #Script = #Script+script
FROM #procedure
DECLARE #pos INT =7500
SELECT #pos=CHARINDEX(CHAR(13)+CHAR(10),#script,#pos)
PRINT SUBSTRING(#Script,1,#Pos)
DECLARE #Counter INT
SET #Counter = 0
DECLARE #TotalPrints INT
SET #TotalPrints = ( LEN(#script) / 8000 )
WHILE #Counter < #TotalPrints
BEGIN
SET #Counter = #Counter + 1
PRINT SUBSTRING(#script,#pos+1,7500)
SET #pos = #pos+7500
SELECT #pos=CHARINDEX(CHAR(13)+CHAR(10),#script,#pos)
END
END
Basically what the procedure is doing it just prints the procedure code. But the problem I am facing is when I am printing it i am loosing some characters in between.
Can anyone let me know where I am going wrong?
Why do you want to print ?
Why you don't do a select with the script, put it in xml if you want to see everything.
Select Convert(xml, #script)
EDIT :
between you don't need to do +1
PRINT SUBSTRING(#script,#pos,7500)

SQL Cursor within Stored Procedure to populate string variable

I have a stored procedure that contains a cursor to loop through SQL records and populates the string which I will use later as my email text. I'm trying to print it out to verify before I can proceed with it but it seems to not populate the string. Here is my stored procedure in SQL Server 2005.
CREATE PROCEDURE [dbo].[spBody]
AS
DECLARE #MyCursor CURSOR
DECLARE #emailBody nvarchar(max)
DECLARE #statusName nvarchar(max)
DECLARE #deptCode nvarchar(max)
DECLARE #instructors nvarchar(max)
DECLARE #meetingTime nvarchar(max)
SET #MyCursor = CURSOR FAST_FORWARD For
Select StatusName, DeptCode, Instructors, Description from MyTable where StatusID = (select CAST(value AS INT) from Table2 where ConfigOption = 'RequiredStatus')
Open #MyCursor
FETCH NEXT FROM #MyCursor INTO #statusName, #deptCode, #instructors, #meetingTime
WHILE ##FETCH_STATUS = 0
BEGIN
SET #emailBody = #emailBody + #statusName + ' ' + #deptCode + ' ' + #instructors + ' ' + #meetingTime
FETCH NEXT FROM #MyCursor INTO #statusName, #deptCode, #instructors, #meetingTime
END
CLOSE #MyCursor
Print #emailBody
DEALLOCATE #MyCursor
It's because #emailBody starts out as NULL, and any concatenation with NULL yields NULL by default. Do a
SET #emailBody = '';
at the beginning of your script.
Also, strongly consider adding a SET NOCOUNT ON; statement at the top of your stored procedure -- not having NOCOUNT ON can greatly slow the execution of your proc.
Why do you need a cursor for this string concat. Wont the following query suffix
DECLARE #emailBody nvarchar(max)
Set #emailBody = ''
Select #emailBody = #emailBody + StatusName + ' ' + DeptCode + ' ' + Instructors + ' ' + [Description] from MyTable where StatusID = (select CAST(value AS INT) from Table2 where ConfigOption = 'RequiredStatus')
Print #emailBody