using Sql Server OPENROWSET with Stored Procedure [duplicate] - sql

I want pass dynamic URL of excel to "OPENROWSET".
NOTE - I am passing returned result of excel file to cursor.
I want to pass file path to "#excelpath",
I have tried many ways but its giving syntax error.
ALTER procedure [dbo].[import_excel]
(
#excelpath as nvarchar(max)
)
as
begin
set nocount on
DECLARE insert_cursor CURSOR FOR
select * FROM OPENROWSET('Microsoft.ACE.OLEDB.12.0',
'Excel 12.0;Database=C:\memberdata.xlsx', [Sheet1$])
OPEN insert_cursor;
FETCH NEXT FROM insert_cursor
INTO #id_number, #memberName
WHILE ##FETCH_STATUS = 0
BEGIN
-- body of cursor
FETCH NEXT FROM insert_cursor
INTO #id_number, #memberName
END
CLOSE insert_cursor;
DEALLOCATE insert_cursor;
END

You have to build your query using dynamic SQL, as shown in this question. It would probably be simplest for you to insert the data from your query into a permanent table, then run the cursor over the permanent table. In that way you minimize the amount of SQL you need to work with dynamically.

Related

How to execute single sql query in multiple databases

I have cloud server where I've hosted a web application for my customers. Each customer has a different SQL database and website in IIS. Whenever I want to execute a sql query to update something, I have to do this manually in each database. There are almost 50 databases and it takes around an hour in executing single query each time. Can someone provide me a tool or way by which I just select all the database at once and execute that query simply?
If I guess you have all databases are in same structure and every time you run script to update something, the script basically same and you just run that same script one by one for each customer.
If the above case is true, you can use CURSOR to produce a Loop between your all databases and Execute necessary script to serve your purpose.
Note: This is not the solution, Just Idea.
--The first step will be creating a Table variable
--where you will INSERT all your database names
--for a further loop as below-
DECLARE #DbName VARCHAR(200)
DECLARE #DatabaseList TABLE (DbName VARCHAR(200))
INSERT INTO #DatabaseList (DbName) VALUES('db_name_1')
INSERT INTO #DatabaseList (DbName) VALUES('db_name_2')
--.......................
INSERT INTO #DatabaseList (DbName) VALUES('db_name_50')
--Now you can use CURSOR to generate the loop
--and execute your required script as shown below
DECLARE db_cursor CURSOR FOR
SELECT DbName FROM #DatabaseList
OPEN db_cursor
FETCH NEXT FROM db_cursor INTO #DbName
WHILE ##FETCH_STATUS = 0
BEGIN
--HERE You need to write your script That you
--Execute for all your database. I have added
--a sample script where I guess you updating
--certain tables in your all database WHERE ID = 1
-- You can see the Database Name inserted in the
-- Script Dynamically from the Loop
EXEC ('UPDATE '+#DbName+'.dbo.<Your_table_Name_Here>
WHERE ID=1')
--END OF Dynamic Part
FETCH NEXT FROM db_cursor INTO #DbName
END
CLOSE db_cursor
DEALLOCATE db_cursor

loop through results and create views for a new database

I am using SQL Server 2012.
I am copying some view from one database to another one. I know I can use Task > Generate scripts to do this for me, however I would like to know how to do this in a different way.
If I run the query select * FROM INFORMATION_SCHEMA.VIEWS it will obviously return my a list of views in my current database. In the view_definition column I can see it has the scripts to create the views.
Would I would like to know is how to loop through the results from (select * FROM INFORMATION_SCHEMA.VIEWS) and execute the scripts in the view_definition field? I understand this may not be the best practise however I would just like to learn how you would do such a thing.
You could try opening a cursor and creating the view for each row :
USE [Target DB];
DECLARE #view VARCHAR(MAX)
DECLARE curs CURSOR
FOR SELECT VIEW_DEFINITION FROM [Source DB].INFORMATION_SCHEMA.VIEWS
OPEN curs
FETCH NEXT FROM curs
INTO #view
WHILE ##FETCH_STATUS = 0
BEGIN
EXEC(#view)
FETCH NEXT FROM curs
INTO #view
END
CLOSE curs
DEALLOCATE curs

execute stored procedures returned from database table

I am working with sql server 2008
I have a database table that has a column containing a stored procedure name.
I want to query the database table which returns a list of the stored procedure names, and execute them.
The stored procedures are similar all having a select statment. The data returned in this select statement I want to insert in to a data base table.
Pseudo code looks like this:
INSERT INTO MyTable
EXECUTE sp_executesql SELECT StoredProcedureName FROM Table
Anyone able to assist me with correct sql for achieveing the above?
sp_executesql accepts a unicode string not a tsql statement. So you would need to execute your procedure(s) like this:
execute sp_executesql 'execute ' + #storedprocedurename
which will execute a single procedure.
You will need to write some iterative process to populate the #storedprocedurename variable from your source table.
This is pretty much same as #Coltech answer just with cursor.
DECLARE #spname VARCHAR(200)
DECLARE #sql VARCHAR(1000)
DECLARE your_cursor CURSOR FOR
SELECT spname
FROM yourTable;
OPEN your_cursor;
FETCH NEXT FROM your_cursor
INTO #spname;
WHILE ##FETCH_STATUS = 0
BEGIN
SET #sql = 'EXEC ' + #spname
execute sp_executesql #sql
FETCH NEXT FROM your_cursor
INTO #spname;
END
CLOSE your_cursor;

How to check if cursor exists (open status)

How do I check if a cursor is open or not? Because many times I am encountering the error 'Cursor already exists'. Please let me know how can I check whether a cursor is already in open status.
In fact I have closed as well as Deallocated it at the end (CLOSE ppm_cursor; DEALLOCATE ppm_cursor;) But Still i am getting the same error what could be the reason.
You can use the CURSOR_STATUS function to determine its state.
IF CURSOR_STATUS('global','myCursor')>=-1
BEGIN
DEALLOCATE myCursor
END
Close the cursor, if it is empty then deallocate it:
IF CURSOR_STATUS('global','myCursor') >= -1
BEGIN
IF CURSOR_STATUS('global','myCursor') > -1
BEGIN
CLOSE myCursor
END
DEALLOCATE myCursor
END
Just Small change to what Gary W mentioned, adding 'SELECT':
IF (SELECT CURSOR_STATUS('global','myCursor')) >= -1
BEGIN
DEALLOCATE myCursor
END
http://social.msdn.microsoft.com/Forums/en/sqlgetstarted/thread/eb268010-75fd-4c04-9fe8-0bc33ccf9357
I rarely employ cursors, but I just discovered one other item that can bite you here, the scope of the cursor name.
If the database CURSOR_DEFAULT is global, you will get the "cursor already exists" error if you declare a cursor in a stored procedure with a particular name (eg "cur"), and while that cursor is open you call another stored procedure which declares and opens a cursor with the same name (eg "cur"). The error will occur in the nested stored procedure when it attempts to open "cur".
Run this bit of sql to see your CURSOR_DEFAULT:
select is_local_cursor_default from sys.databases where name = '[your database name]'
If this value is "0" then how you name your nested cursor matters!
This happened to me when a stored procedure running in SSMS encountered an error during the loop, while the cursor was in use to iterate over records and before the it was closed. To fix it I added extra code in the CATCH block to close the cursor if it is still open (using CURSOR_STATUS as other answers here suggest).
Expanding on a previous answer, this proc is useful to call if you are worried that the cursor may have been left open or allocated
CREATE OR ALTER PROCEDURE dbo.CloseAndDeallocateCursor
#cursorName NVARCHAR(80)
AS
BEGIN
IF CURSOR_STATUS('global', #cursorName) >= -1
BEGIN
DECLARE #SQL NVARCHAR(91)
IF CURSOR_STATUS('global', #cursorName) > -1
BEGIN
SET #SQL = N'CLOSE ' + #cursorName
EXEC sp_executeSQL #SQL
END
SET #SQL = N'DEALLOCATE ' + #cursorName
EXEC sp_executeSQL #SQL
END
END
GO
... and then sample usage ...
EXEC dbo.CloseAndDeallocateCursor 'myCursor'
DECLARE myCursor STATIC
FOR SELECT * FROM blah

MSSQL: How do you script Stored Procedure creation with code?

I am trying to query for a list of stored procedure definitions using information_schema.routines that exist in one database but not in another.
SELECT
t1.Routine_Definition
FROM
[server1].MyDatabase.INFORMATION_SCHEMA.Routines t1
LEFT JOIN
[server2].MyDatabase.INFORMATION_SCHEMA.Routines t2 ON t1.Routine_Name = t2.Routine_Name
WHERE
t2.Routine_Name is null
This gives me the query definitions in a single line so when I have a comment like this
--Some comment
SELECT Column
FROM Somewhere
The SQL gets commented out and I cannot use the definition to create the SP.
How to I parse this back with the proper line breaks?
or
Is there a better way to get these scripts (using code)?
The stored procedure is only displayed on one line in Management Studio. If you run the query with results to text, or use the following, you will get the correct line breaks:
declare #sql varchar(8000) -- varchar(max) in SQL 2005+
SELECT
#sql = t1.Routine_Definition
FROM
INFORMATION_SCHEMA.Routines t1
print #sql
DECLARE MY_CURSOR Cursor
FOR
SELECT
t1.Routine_Definition
FROM
[server1].MyDatabase.INFORMATION_SCHEMA.Routines t1
LEFT JOIN
[server2].MyDatabase.INFORMATION_SCHEMA.Routines t2 ON t1.Routine_Name = t2.Routine_Name
WHERE
t2.Routine_Name is null AND
LEN(t1.Routine_Definition) < 4000
Open My_Cursor
DECLARE #sql VARCHAR(MAX)
FETCH NEXT FROM MY_Cursor INTO #sql
While (##FETCH_STATUS <> -1)
BEGIN
IF (##FETCH_STATUS <> -2)
Print #sql
FETCH NEXT FROM MY_CURSOR INTO #sql
END
CLOSE MY_CURSOR
DEALLOCATE MY_CURSOR
GO
Here is how I implemented ck's solution...
the INFORMATION_SCHEMA view only returns the first 4000 characters in the definition. (Ideally you wont have SP that are that long)You will want to script those manually or some other way.
I think the easiest way of getting your stored procedures is to use the Import/Export utility that is built into SQL Server Management Studio. From there you can export your Stored Procedure Objects into the code window or to a file that you can immediately run.