loop through results and create views for a new database - sql

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

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

Best way to replace cursor in SQL Server 2008

I want to replace the cursor code from my stored procedure
DECLARE CursorXD CURSOR FOR
SELECT
IDOrdre, Quantity,fabnum
FROM prod_ordreplanificationdetail
WHERE fab = #num
AND ordre = #ord
OPEN CursorXD
FETCH NEXT FROM CursorXD INTO #correctionnumsap, #correctionquantite, #correctionnumfabrication
WHILE ##FETCH_STATUS = 0
BEGIN
EXEC INSERT#prod #idordre = #correctionnumsap,
#quantite = #correctionquantiteneg,
#fabnum = #correctionnumfabrication
FETCH NEXT FROM CursorXD INTO #correctionnumsap, #correctionquantite, #correctionnumfabrication
END
CLOSE CursorXD
DEALLOCATE CursorXD
What is the best way to replace this cursor to increase the performance??
Any suggestion?
Here's a option, but I made a couple of assumptions
INSERT INTO prod
SELECT IDOrdre, Quantity,fabnum
FROM prod_ordreplanificationdetail
WHERE fab=#num
AND ordre=#ord
Assumptions:
SP INSERT#prod only does an INSERT and no other data manipulation
SP INSERT#prod inserts into a table called prod and there are only three columns in the table
You can use WHILE loop instead of CURSOR by maintaining the nth row value. It is too good performance wise compare to CURSOR. If you tell clearly what you need, so we can walk into same road.

using Sql Server OPENROWSET with Stored Procedure [duplicate]

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.

REPLACE in Sql replaces more than once issue

Weird not sure if I have it correct but the output is weird:
select *
into #TempScormModuelsTable
from Scorm.ScormModules
select * from #TempScormModuelsTable
DECLARE #ScormModuleId int
DECLARE db_cursor CURSOR FOR
SELECT ScormModuleId from #TempScormModuelsTable
OPEN db_cursor
FETCH NEXT FROM db_cursor INTO #ScormModuleId
WHILE ##FETCH_STATUS = 0
BEGIN
update #TempScormModuelsTable
set Directory = REPLACE(Directory,'SCORM','ScormPackages'),
RelativeHtmlPath = REPLACE(RelativeHtmlPath,'SCORM','ScormPackages')
FETCH NEXT FROM db_cursor INTO #ScormModuleId
END
--drop table #TempScormModuelsTable
CLOSE db_cursor
DEALLOCATE db_cursor
then in the column Directory I have this!
E:\inetpub\www.sellandprosper.com\ScormPackagesPackagesPackagesPackagesPackagesPackagesPackagesPackages\SellingOfficeWithNewPCs
"ScormPackagesPackagesPackagesPackagesPackagesPackagesPackagesPackages" was "SCORM" and I just want it as ScormPackages..yikes
any help?
That's not SQL.
You need something closer to...
UPDATE
Scorm.ScormModules_backup
SET
Directory = REPLACE(Directory, 'SCORM', 'ScormPackages'),
RelativeHtmlPath = REPLACE(RelativeHtmlPath, 'SCORM', 'ScormPackages')
SQL is already set based and this will naturally apply this to every row (much like your FOREACH pseudocode).
I'm not sure what your WHERE clause is meant to do, but you can append WHERE clauses to UPDATEs too.
EDIT
Okay you just totally changed the code in your question.
Now, you're looking in a cursor, but the update is being done to the whole table.
So, if you have 8 rows, you do the update 8 times. But each time you do it to every row in the table.

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.