cursor not adding data, adding only when executing separately - sql-server

I have stored procedure & cursor loop which I am using to add data in main table issue is I am adding data from csv file to temp table and from temp table to main table
alter PROCEDURE [dbo].[CreateHub]
#HubName varchar(100)
AS
INSERT INTO dbo.HUB1
(HUB_NAME)
SELECT #HubName
WHERE (NOT EXISTS
(SELECT ID_HUB, HUB_NAME
FROM dbo.HUB1
WHERE (HUB1.hub_name = #HubName)))
SELECT ID_HUB AS newHubId
FROM dbo.HUB1
WHERE (hub1.hub_name = #HubName)
GO
Once this is done, there is another code which is doing bulk insert from csv file and running cursor loop for adding data in main table
bulk insert [dbo].[HUB_temp]
from 'C:\POPAD-DAT\HUB1.csv'
with (fieldterminator = ',', rowterminator = '\n')
go
DECLARE #sSQL AS nVARCHAR(100)
DECLARE #ItemsFromCSV AS nvarchar(200)
DECLARE sql_cursor_hub CURSOR
FOR SELECT HUB_NAME FROM HUB_temp
OPEN sql_cursor_hub
FETCH NEXT FROM sql_cursor_hub
INTO #ItemsFromCSV -- Multiple variables for multiple CSV columns will be required
WHILE ##FETCH_STATUS = 0
BEGIN
set #sSQL = 'EXEC [dbo].[CreateHub] ' + #ItemsFromCSV -- AND OTHER Parameters
print #sSQl
EXECUTE sp_executesql #sSQL
FETCH NEXT FROM sql_cursor_hub
END
CLOSE sql_cursor_hub;
DEALLOCATE sql_cursor_hub;
Running cursor is not adding data its showing like same id and showing different u=hubname but not inserting data
While if I am running separately executing SP it is adding like this
EXEC [dbo].[CreateHub] 'SGGSP30'
EXEC [dbo].[CreateHub] 'USGSP20'
can you please help where exactly iam going wrong

You forgot to do INTO in the second fetch
WHILE ##FETCH_STATUS = 0
BEGIN
set #sSQL = 'EXEC [dbo].[CreateHub] ' + #ItemsFromCSV -- AND OTHER Parameters
print #sSQl
EXECUTE sp_executesql #sSQL
-- This is changed
FETCH NEXT FROM sql_cursor_hub INTO #ItemsFromCSV
END
You should also take care of your parameter declarations, #ItemsFromCSV is varchar(200) but the stored proc parameter is only varchar(100) and #sSQL is only 100 in size but you add #ItemsFromCSV to it.

Related

Execute queries stored in columns of a SQL Server table

I have a table with 2 columns QueryName and Query. I am trying the execute the queries stored in the Query column of the table.
I want to display anything that has more than record count of zero, we need to print to output with queryname and count. I am using the following cursor, I was able to display rowcount but anyone please suggest me how to display the QueryName:
DECLARE #Sql NVARCHAR(MAX);
DECLARE Cur CURSOR LOCAL FAST_FORWARD FOR
(SELECT Query
FROM VWLetterTYB )
OPEN Cur
FETCH NEXT FROM Cur INTO #Sql
WHILE (##FETCH_STATUS = 0)
BEGIN
--Exec sp_executesql #Sql
EXEC ('SELECT COUNT(*) AS Rowcounts FROM (' + #sql + ') AS t HAVING COUNT(*) > 0 ')
FETCH NEXT FROM Cur INTO #Sql
END
CLOSE Cur
DEALLOCATE Cur;
DECLARE #Sql NVARCHAR(MAX);
DECLARE Cur CURSOR LOCAL FAST_FORWARD FOR
(SELECT Query
FROM VWLetterTYB )
OPEN Cur
FETCH NEXT FROM Cur INTO #Sql
WHILE (##FETCH_STATUS = 0)
BEGIN
--Exec sp_executesql #Sql
EXEC ('SELECT [sql] = ''' + #Sql + ''', COUNT(*) AS Rowcounts FROM (' + #sql + ') AS t HAVING COUNT(*) > 0 ')
FETCH NEXT FROM Cur INTO #Sql
END
CLOSE Cur
DEALLOCATE Cur;
If I understand you correctly, you have two fields in the table but you only managed to get one using the cursor. In that case, the solution is easy, you can fetch more than one value with a cursor (each one to a different variable), then just put that value in the dynamic SELECT:
DECLARE #Sql NVARCHAR(MAX), #QueryName NVARCHAR(MAX);
DECLARE Cur CURSOR LOCAL FAST_FORWARD FOR
(SELECT Query, QueryName
FROM VWLetterTYB )
OPEN Cur
-- variables are filled in the order used in the SELECT (first column to first variable,
-- second column to second variable, etc.)
FETCH NEXT FROM Cur INTO #Sql, #QueryName
WHILE (##FETCH_STATUS = 0)
BEGIN
-- when using single quotes inside a string you have to double it
EXEC ('SELECT '''+ #QueryName+''' AS QueryName, COUNT(*) AS Rowcounts FROM (' + #sql + ') AS t HAVING COUNT(*) > 0 ')
FETCH NEXT FROM Cur INTO #Sql, #QueryName
END
CLOSE Cur
DEALLOCATE Cur;
I don't have an answer, but a further refinement of the question. The examples here are using the stored SQL as a standalone command. Can a snippet of SQL stored in a table's column be used as an item in a SELECT list?
I have a situation where I have a table of code/name lookup pairs. Most codes lead to a single name. But something logic needs to be applied to determine the name. I would like to have this seamless in my master SQL statement. I have to apply this logic from the same lookup table in many scripts. I don't want to have to embed complex logic in each script or maintain a convoluted stored procedure.

Need help. Message says temp table doesn't exist: 'Invalid object name '#TempCodes'.'

If I run the select statement below by itself (with the table name hard coded in) it runs fine and the temp table is created. If I run it as below it says 'Invalid object name '#TempCodes'' although when I print #Sql1 it looks exactly the same as when I run it by itself (with the table name hard coded in).
Any ideas on what's going on here will be appreciated.
DECLARE #TableName NVARCHAR(50)
SET #TableName = '[My Table Name]'
DECLARE #Sql1 NVARCHAR(MAX);
SET #Sql1 = N'SELECT AccountNumber,LTRIM(RTRIM(m.n.value(''.[1]'',''varchar(8000)''))) AS mdcodes INTO #TempCodes FROM (SELECT AccountNumber,CAST(''<XMLRoot><RowData>''
+ REPLACE(MD_Results,'','',''</RowData><RowData>'')
+ ''</RowData></XMLRoot>'' AS XML) AS x FROM ' + #TableName
+ N')t CROSS APPLY x.nodes(''/XMLRoot/RowData'')m(n)'
IF OBJECT_ID('tempdb.dbo.#TempCodes', 'U') IS NOT NULL
BEGIN
drop table #TempCodes
END
EXECUTE sp_executesql #Sql1
Select * from #TempCodes
I believe ## is a typo. Even if you fix it to # it will throw same error.
EXECUTE sp_executesql #Sql1
A local temporary table created in a stored procedure is dropped
automatically when the stored procedure is finished.
In your case sp_executesql is the stored procedure.
the table created inside the dynamic query will be dropped after the exec sp_executesql is completed. That's why you are getting that error.
You need to create table outside and use Insert into table..select syntax inside the dynamic query
IF OBJECT_ID('tempdb.dbo.#TempCodes', 'U') IS NOT NULL
drop table #TempCodes
create table #TempCodes(AccountNumber varchar(100),mdcodes varchar(100))
SET #Sql1 = N'Insert into #TempCodes
SELECT AccountNumber,LTRIM(RTRIM(m.n.value(''.
[1]'',''varchar(8000)''))) AS mdcodes FROM (SELECT
AccountNumber,CAST(''<XMLRoot><RowData>'' +
REPLACE(MD_Results,'','',''</RowData><RowData>'') + ''</RowData></XMLRoot>''
AS XML) AS x FROM '+#TableName+ N')t CROSS APPLY
x.nodes(''/XMLRoot/RowData'')m(n)'
Try using a global temp table ##TempCodes as local temporary tables are only visible in current session.
DECLARE #TableName NVARCHAR(50)
SET #TableName = '[My Table Name]'
DECLARE #Sql1 NVARCHAR(MAX);
SET #Sql1 = N'SELECT AccountNumber,LTRIM(RTRIM(m.n.value(''.
[1]'',''varchar(8000)''))) AS mdcodes INTO ##TempCodes FROM (SELECT
AccountNumber,CAST(''<XMLRoot><RowData>'' +
REPLACE(MD_Results,'','',''</RowData><RowData>'') + ''</RowData></XMLRoot>''
AS XML) AS x FROM '+#TableName+ N')t CROSS APPLY
x.nodes(''/XMLRoot/RowData'')m(n)'
IF OBJECT_ID('tempdb.dbo.##TempCodes', 'U') IS NOT NULL
BEGIN
drop table ##TempCodes
END
EXECUTE sp_executesql #Sql1
Select * from ##TempCodes

Use "the USE [Database]" statement dynamically inside a SQL stored procedure

I've created a stored procedure where I want to pass the #DB through a USE command. I know I can define dynamically the correct path for the table with the name of the DB (e.g. ... '+ #DB +' .dbo.tAnalysisResult' ) but I have several inner joins with many tables on the same database so I'd like to define the DB only once at the beginning.
Any help will be highly appreciated. Below my query which currently doesn't work:
USE [DB_Research]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].sp_test1 #DB VARCHAR(300), #OUTCOME INT OUTPUT
AS
SET NOCOUNT ON
EXECUTE ('USE' + #DB)
BEGIN TRY
SELECT #OUTCOME = (select SUM(ResultSID) from tAnalysisResult)
END TRY BEGIN CATCH
-- If error encountered, display it
SELECT #OUTCOME = '0, line: ' + CAST(ERROR_LINE() AS VARCHAR(MAX)) + ', msg:' + ERROR_MESSAGE()
END CATCH
SET NOCOUNT OFF
-- Execute the stored procedure
declare #OUTCOME INT
exec sp_test1 'Loss_DB', #OUTCOME OUTPUT
Print(#OUTCOME)
Select * from dbname..schemaname.tablename

Execute procedure executing same statement twice

I have written this procedure,
DECLARE CURS_TABLE CURSOR FOR
SELECT NAME FROM SYS.TABLES WHERE NAME LIKE 'AK_LIB_ADDRESS'
DECLARE #TABLE_NAME VARCHAR(100);
DECLARE #SQL VARCHAR(300);
OPEN CURS_TABLE
FETCH NEXT FROM CURS_TABLE INTO #TABLE_NAME;
WHILE ##FETCH_STATUS = 0
BEGIN
SET #SQL = 'ALTER TABLE '+#TABLE_NAME+' ADD PRIMARY KEY(ID);';
EXEC (#SQL)
FETCH NEXT FROM CURS_TABLE INTO #TABLE_NAME
END
CLOSE CURS_TABLE;
DEALLOCATE CURS_TABLE;
The problem is the exec(#sql) executing the same statement twice, i checked by placing print statement,it's working fine with print statement if i comment exec line...
So please can u give me any idea where i'm doing wrong..?
You should do like this, used a temporary table instead of selecting directly from the sys.tables
SELECT NAME into #temp FROM SYS.TABLES WHERE NAME LIKE 'AK_LIB_ADDRESS%'
DECLARE CURS_TABLE CURSOR FOR
SELECT NAME from #temp
DECLARE #TABLE_NAME VARCHAR(100);
DECLARE #SQL VARCHAR(300);
OPEN CURS_TABLE
FETCH NEXT FROM CURS_TABLE INTO #TABLE_NAME;
WHILE ##FETCH_STATUS = 0
BEGIN
select #TABLE_NAME
SET #SQL = 'ALTER TABLE '+#TABLE_NAME+' ADD PRIMARY KEY(ID);';
EXEC (#SQL)
FETCH NEXT FROM CURS_TABLE INTO #TABLE_NAME
END
CLOSE CURS_TABLE;
DEALLOCATE CURS_TABLE;
Or add a Insensitive keyword to the cursor. The reason is that you are changing a heap to the B-tree inside the trigger, that's the reason you are getting inconsistent behaviour in the cursor.
DECLARE CURS_TABLE CURSOR INSENSITIVE FOR
SELECT NAME FROM SYS.TABLES WHERE NAME LIKE 'AK_LIB_ADDRESS%'
DECLARE #TABLE_NAME VARCHAR(100);
DECLARE #SQL VARCHAR(300);

Excel file has bigger size using OPENQUERY to update it

Maybe the solution can be so easy but I can't find it so I write here for some help.
We have this sql function:
CREATE FUNCTION [dbo].[updateExcel]
(
-- Add the parameters for the function here
#cell VARCHAR(4),
#description VARCHAR(200)
)
RETURNS BIT
AS
BEGIN
DECLARE #sql NVARCHAR(1000)
SET #sql = 'UPDATE openquery(LinkedServer2ExcelFile, ''SELECT * FROM [Sheet1$'+#cell+':'+#cell+']'') set F1 = '''+#description+''''
--PRINT #sql
EXEC sp_executesql #sql
RETURN 0
END
that we use to update some excel file
EXEC #Result = updateExcel 'somecell', 'somevalue'
The problem is that after this update the excel has a bigger size. But when we open it and save it again, the file's size get normal again
I hope to find here some answers ...
Thanx !!!

Resources