Cursor not open - sql

I'm trying to create table using statements stored in table. I'm using a cursor with execute(sql) as below:
create table tab
(
CreateSql varchar(250)
)
insert into tab values ('create table tab1 (id int )')
insert into tab values ('create table tab2 (id int )')
insert into tab values ('create table tab3 (id int )')
declare cur cursor for
select createsql
from tab
declare #sql varchar(255)
open cur
fetch cur into #sql
while ##SqlStatus = 0
begin
execute(#Sql)
fetch cur into #sql
end
close cur
deallocate cursor cur
If I run it then appears an error :
Could not execute statement. Cursor not open SQLCODE=-180, ODBC 3
State="34000"
The first table (tab1) will create, but other (tab2, tab3) tables not.
If I replace statement execute(sql) with select sql, script will work correctly.
Thanks in advance for your answer.
PX

IQ likes to close the cursor after the first commit.
You need to use the WITH HOLD clause (or something along those lines) to keeps the cursor open.

Why dont you do it with while loop.using Cursor is overkill in these scenarios.
I am not familiar with sybase syntax but in SQL Server 2008 you can do like this
create table tab
(
CreateSql varchar(250)
,ID int IDENTITY(1,1)
)
insert into tab values ('create table tab1 (id int )')
insert into tab values ('create table tab2 (id int )')
insert into tab values ('create table tab3 (id int )')
DECLARE #max INT = (SELECT MAX(ID) FROM tab)
,#index int =1
,#sql varchar(255)
while (#index<= #max )
begin
select #sql= createsql from tab WHERE ID=#index
execute(#Sql)
SET #index = #index+1
end

I'm not a sybase expert but it looks like you missing next on the fetch statement.
fetch next cur into #sql

Related

How to insert records in a existing table using Cursor

Declare Userrole_Cursor Cursor For
Select (User_Role_id,
Pos_entity_Id,
User_role_code,
User_Role_description,
Print_Sequence,
Update_date,
Tx_id,
Add_date,
Add_Username,
Update_Username,
Active_Flag) from User_Role_Tb where pos_entity_id = (pos_entity_id)
Open Cursor
FETCH NEXT FROM UserRole_Cursor into
the above is the Cursor creation i have written, now need to insert in all the mentioned columns in a User_role_tb. please help. this is the first time i am using cursor.
This simple example can help you
-- assume this is your table
create table #tmp (MyDbName varchar(100), MyDbId int, MyStatus int)
-- you need to have a variable for each field.
DECLARE #MyDbName varchar(100)
DECLARE #MyDbId int
DECLARE #MyDbStatus int
DECLARE db_cursor CURSOR FOR
SELECT name, [dbid], [status]
FROM master.dbo.sysdatabases
OPEN db_cursor
FETCH NEXT FROM db_cursor INTO #MyDbName, #MyDbId, #MyDbStatus
WHILE ##FETCH_STATUS = 0
BEGIN
-- insert data into your table using variables
insert into #tmp (MyDbName, MyDbId, MyStatus)
values (#MyDbName, #MyDbId, #MyDbStatus)
-- fetch next row from cursor
FETCH NEXT FROM db_cursor INTO #MyDbName, #MyDbId, #MyDbStatus
END
CLOSE db_cursor
DEALLOCATE db_cursor
-- select from your table to make sure data is there
select * from #tmp

How to insert result of Stored Procedure into Temp Table without declaring Temp Table Columns

I want to insert the values of stored procedure into a temp table without predefining the columns for the temp table.
Insert Into #Temp1 Exec dbo.sp_GetAllData #Name = 'Jason'.
How can I do this ? I saw an option as below but can I do it without mentioning the server name ?
SELECT * INTO #TestTableT FROM OPENROWSET('SQLNCLI', 'Server=localhost;Trusted_Connection=yes;',
'EXEC tempdb.dbo.GetDBNames')
-- Select Table
SELECT *
FROM #TestTableT;
I could not find a possible solution without defining temp table schema and writing server name. So, I changed the code and the queries to handle with only known schema. Code example is as below
CREATE TABLE #TestTable ([name] NVARCHAR(256), [database_ID] INT);
INSERT INTO #TestTable
EXEC GetDBNames
SELECT * FROM #TestTable;
As provided in the link https://blog.sqlauthority.com/2013/05/27/sql-server-how-to-insert-data-from-stored-procedure-to-table-2-different-methods/
No-one said it had to be pretty:
CREATE PROCEDURE p AS
SELECT 1 as x, 2 as y, 3 as z
GO
DECLARE c CURSOR FOR
SELECT
name, system_type_name
FROM sys.dm_exec_describe_first_result_set_for_object(OBJECT_ID('p'), 0);
DECLARE #name sysname, #type sysname;
CREATE TABLE #t(fake int)
OPEN c
FETCH NEXT from c into #name, #type
WHILE (##FETCH_STATUS = 0)
BEGIN
EXEC ('ALTER TABLE #t ADD ' + #name + ' ' + #type)
FETCH NEXT from c into #name, #type
END
CLOSE C
DEALLOCATE c
ALTER TABLE #t DROP COLUMN fake;
INSERT INTO #t EXEC p;
GO

drop the bulk table from database

I want to drop bulk table from database whose name is starts with some string.
create table #Temp
(
TableName varchar(50)
)
Insert into #Temp
SELECT NAME FROM SYS.OBJECTS WHERE TYPE='U' NAME LIKE '%'
DECLARE #Name varchar(50)
DECLARE cursorName CURSOR -- Declare cursor
LOCAL SCROLL STATIC
FOR
Select TableName FROM Temp
OPEN cursorName -- open the cursor
FETCH NEXT FROM cursorName
INTO #Name
WHILE ##FETCH_STATUS = 0
BEGIN
FETCH NEXT FROM cursorName
INTO #Name
drop table #Name
END
CLOSE cursorName -- close the cursor
DEALLOCATE cursorName -- Deallocate the cursor
Note : This will work if the table which u are talking abt doesnt have table depedencies .

Declare a Cursor From a Table as Variable (In the Select-Statement)

I want to create a SP that have 2 String parameters for 2 table names. In the SP I use dynamic SQL to modify one of the tables, but the other is inside a cursor, and I cant use dynamic SQL after the "FOR"
ALTER PROCEDURE NameProcedure #SourceTable VARCHAR(100),#DestinationTable VARCHAR(100)
AS
BEGIN
DECLARE #AddressSource VARCHAR(100), #AddressDestination VARCHAR(100)
SELECT #AddressSource = '[Test_Toa].[dbo].[' + #SourceTable + ']'
SELECT #AddressDestination = '[Test_Toa].[dbo].[' + #DestinationTable + ']'
--Source Table columns
DECLARE #id int, #idmercado int, #idcadena int, #barcode nvarchar(255),#Complete_P nvarchar(MAX)
DECLARE #Cursor CURSOR
SET #Cursor = CURSOR FOR
--HEREE ITS MY PROBLEM :(!!!!!
SELECT id, idmercado, idcadena, barcode, precios + ',' FROM #AddressSource
OPEN #Cursor
FETCH NEXT
FROM #Cursor INTO #id,#idmercado,#idcadena,#barcode,#Complete_P
WHILE ##FETCH_STATUS = 0
BEGIN
--bla bla code
FETCH NEXT
FROM #Cursor INTO #id,#idmercado,#idcadena,#barcode,#Complete_P
END
CLOSE #Cursor
DEALLOCATE #Cursor
END
I just want to declare a cursor for the table that the user gives
Well, you need to write a dynamic sql statement. Just as an hint. You can copy the values from your given source table into a temp table, generate a cursor on the temp table, iterate through it and deallocate the cursor afterwards and drop the temp table. :-)
Here a short demo code:
DECLARE #sql nvarchar(max), #sourceTable nvarchar(255)
CREATE TABLE dbo.t1(id int, name nvarchar(200))
CREATE TABLE dbo.t2(id int, name nvarchar(200))
SET #sourceTable = N'dbo.t1'
CREATE TABLE #temp(id int, name nvarchar(200))
SET #sql = N'
INSERT INTO #temp(id,name)
SELECT id, name
FROM '+#sourceTable
EXEC(#sql)
DECLARE cur CURSOR FOR
SELECT id, name
FROM #temp
OPEN cur
DECLARE #id int, #name nvarchar(200)
FETCH NEXT FROM cur INTO #id, #name
WHILE ##fetch_status = 0 BEGIN
SELECT #id, #name -- demo output
FETCH NEXT FROM cur INTO #id, #name
END
-- cleanup
CLOSE cur
DEALLOCATE cur
DROP TABLE dbo.t1
DROP TABLE dbo.t2
DROP TABLE #temp
Beware, I just have written this in notepad without any database. But I'm quite sure it does it's job.
This just works if all available variants of #sourceTable have the same column specification. If not, you need to extract the needed columns from information schema and build a more dynamic code.

Append result of stored procedure to earlier executed stored procedure

I have a stored procedure which takes a single parameter containing single value.
I want to pass a collection of values to the procedure one by one and get the combined result into one table . Is this possible ?
Currently I am using cursor to execute procedure in loop but only result from passing first value in the collection is obtained.
declare #clientid varchar(10)
create table #tmpp(secid varchar(10))
insert into #tmpp values(2319)
insert into #tmpp values(2855)
insert into #tmpp values(1303)
declare cur CURSOR LOCAL for
select secid from #tmpp
open cur
fetch next from cur into #seclientid
while ##FETCH_STATUS = 0 BEGIN
exec getReportforclient #clientid
fetch next from cur into #clientid
END
close cur
deallocate cur
drop table #tmpp
If this is too obfuscated / unclear/ silly, can somebody please provide me an alternative ?
Any help is most appreciated . Thanks.
There probably is a way to this without using cursors, but without taking a look at your stored procedure we can't help too much on that. You can create a table (temporary or not) that has the same structure that the results of your sp and insert the results into it. Something like this:
DECLARE #clientid VARCHAR(10)
CREATE TABLE #tmpp(secid VARCHAR(10))
INSERT INTO #tmpp VALUES(2319)
INSERT INTO #tmpp VALUES(2855)
INSERT INTO #tmpp VALUES(1303)
CREATE TABLE #Results(col1 INT, col2.... -- create the table that will hold your
-- results
DECLARE cur CURSOR LOCAL for
SELECT secid
FROM #tmpp
OPEN cur
FETCH NEXT FROM cur INTO #seclientid
WHILE ##FETCH_STATUS = 0
BEGIN
INSERT INTO #Results
exec getReportforclient #clientid
FETCH NEXT FROM cur INTO #clientid
END
CLOSE cur
DEALLOCATE cur
DROP TABLE #tmpp
SELECT *
FROM #Results
Loop without CURSOR
IF OBJECT_ID('tempdb.dbo.#tmpp') IS NOT NULL DROP TABLE #tmpp
CREATE TABLE #tmpp(Clientid varchar(10))
INSERT #tmpp values(2319), (2855), (1303)
IF OBJECT_ID('tempdb.dbo.#Results') IS NOT NULL DROP TABLE #Results
CREATE TABLE #Results(--output columns of procedure)
DECLARE #Clientid int = (SELECT MIN(Clientid) FROM #tmpp)
WHILE (#Clientid IS NOT NULL)
BEGIN
INSERT INTO #Results
EXEC getReportforclient #Clientid
SELECT #Clientid = MIN(Clientid) FROM #tmpp WHERE Clientid > #Clientid
END
Simple example on SQLFiddle