How do I run several .sql scripts from one query? - sql

In SQL Server Management Studio, I want to execute a number of SQL scripts (saved queries) one after the other. This is simply to make it easier to run each. I could take each script and combine them all into one massive script and simply execute the lot, however I want it to all be separate so I can easily and simply run each bit by bit.
For example, something like this:
EXEC ('CreateTable1.sql')
EXEC ('CreateTable2.sql')
EXEC ('CreateSP1.sql')
EXEC ('CreateSP2.sql')
EXEC ('SetupTestData.sql')
And that way I can run each line individually and keep everything separate.

if you like you can run then from the command line using SQLCMD -i, and put the commands in to a batch script. then you can call this from SQL management studio using exec xp_cmdshell. Actually you can be brave and run a FOR command under an xp_cmdshell and do the lot in one line. Or perhaps just run xp_cmdshell on them one by one
Or you can take the approach redgate approach and read the files into variables and then call exec on them. This last approach is serious overkill if all you want to do is exec a few scripts in my opinion.

Related

Stored procedure with bcp hangs, but works when run as a script

I've been working on exporting a table to a file, and had problems with the bcp (bulk copy program) part of the procedure locking up. The code worked fine when I ran it as a script, but would generate locked processes when I wrapped it in a stored procedure.
I seem to have found the solution; COMMIT. Namely, I had to wrap the code which truncated and inserted into the table which bcp would be picking up the data from within a BEGIN TRANSACTION...COMMIT. Now the procedure works
I think it is to do with the command
exec master.dbo.xp_cmdshell #bcp
going outside of the SQL session to the OS. Am I correct, or is there a better explanation?

Call SQL Query from another SQL Server Query (Management Studio)

I know this is redundant, but I'd like to Call Query from another Query. I know I can just add it to first one, but the scripts are getting long and at times I don't want to run all of the queries.
I've been looking and my best guess is maybe just using command shell. I was just wondering if there was another way.
Declare #CommandDos VarChar(150) = 'sqlcmd -E -S Server-i h:\SQL\SomeThing.sql'
EXEC master..xp_cmdshell #CommandDos
Code re-use.
Perhaps use functions, i.e. put the query you want called into a function.
Functions can be Scalar, Table-valued, Deterministic, or Nondeterministic.
Maybe you can create stored procedures with the queries, then call them inside another one if needed.
What do you think about it?

using BCP to export stored procedure result in SQL Server 2008

Heyy,
I'm trying to use BCP to export a SP result to a text file using this query:
EXEC xp_cmdshell 'bcp "exec asmary..usp_Contract_SelectByEmpId -1,1" queryout "C:\test.txt" -w -C OEM -t$ -T -r ~ -S heba\HEBADREAMNET '
The output of this query is telling this error:
Error = [Microsoft][SQL Server Native Client 10.0][SQL Server]Incorrect syntax near the keyword 'where'.
even thought I'm sure that the stored procedure "usp_Contract_SelectByEmpId" is working correctly.
Anyone faced that kind of error before?
As Lynn suggested, check your stored procedure. It looks like the issue is within that.
Ensure any plain SELECT works (e.g., C: drive is database server's local drive, not necessarily your own local drive).
If the first two items work fine, then add SET FMTONLY OFF as follows:
EXEC xp_cmdshell 'bcp "set fmtonly off exec asmary..usp_Contract_SelectByEmpId -1,1" queryout "C:\test.txt" -w -C OEM -t$ -T -r ~ -S heba\HEBADREAMNET'
I have to admit that when I tried similar on my computer it failed with 'Function sequence error', and I found that it is related to a SQL Server 2008 bug fixed in 2011.
Please note also that even without SET FMTONLY OFF everything works with BCP library (odbcbcp.dll/odbcbcp.lib). So, you can have much more generic ODBC-wide bcp solution if you write your own wrapper executable (for instance, in C or C++).
I also found the following at http://msdn.microsoft.com/en-us/library/ms162802.aspx
The query can reference a stored procedure as long as all tables referenced inside the stored procedure exist prior to executing the bcp statement. For example, if the stored procedure generates a temp table, the bcp statement fails because the temp table is available only at run time and not at statement execution time. In this case, consider inserting the results of the stored procedure into a table and then use bcp to copy the data from the table into a data file.
Please see also my later separate reply - I think the whole concept of using stored procedure for BCP/queryout is wrong.
Try this.
DECLARE #strbcpcmd NVARCHAR(max)
SET #strbcpcmd = 'bcp "EXEC asmary..usp_Contract_SelectByEmpId -1,1" queryout "C:\test.txt" -w -C OEM -t"$" -T -S'+##servername
EXEC master..xp_cmdshell #strbcpcmd
Sorry for flooding your question with multiple answers, but I wanted to find out how much heavier (performance-wise) the use of stored procedure is compared to plain SELECT. And I got a very important information from
http://social.msdn.microsoft.com/Forums/en-US/transactsql/thread/b8340289-7d7e-4a8d-b570-bec7a0d73ead/
This forced me to create another (separate) answer. The post I refer to invalidates the whole concept.
In a few words: stored procedure might be called several (3) times in order to figure out the structure of the resultset, then the actual data.
Therefore (and especially if calling from SQL Server connection rather than client), I think it makes a lot more sense to have a stored procedure or function, which will return SELECT statement. Then you can have another generic stored procedure or function to create and execute full BCP command with that statement embedded. I am pretty sure that in this case BCP might use a lot better execution plan. Unfortunately, I cannot verify that in practice, because of BCP bug in SQL Server 2008 R2 I mentioned in my previous post.
N.B. Please be careful creating dynamic queries and escape all explicit literal strings (i.e. repeat all single quotes twice) in order to avoid notorious SQL injection. Unfortunately, there is another pitfall: you should ensure you are not escaping your queries twice or more times.

Updating Stored Procedure on Three Different Servers

I need to update the SQL SERVER stored procedure on three different servers. I do not like to perform this manually. What are my options?
You can use the SQLCMD utility to connect to the three different servers / databases and run the stored procedure script. The control script may look something like this:
:connect server1
use DatabaseName
GO
:r StoredProcedure.sql
GO
:connect server2
use DatabaseName
GO
:r StoredProcedure.sql
GO
:connect server3
use DatabaseName
GO
:r StoredProcedure.sql
GO
SQL Compare is a great tool, especially for large or complex updates. However, you do have to pay for it. Using a utility like SQLCMD is not quite so elegant, but it is quick and free.
Use a tool like Red-Gate SQL Compare to create a script and then use their Multi-Script tool to execute it on multiple servers at one time.
www.red-gate.com
You could use a SQL Server synchronization tool, such as Red Gate SQL Compare. Or you could write a small script / application to connect to each server and execute the update statement, using OSQL.
You can set up some replication between the servers...have 1 main server that you make the update on, and then send that update out to each other server by use of a publication to the other servers. That'd be an easy way to do this.
Check out Migrator.NET, this combined with a builder like Hudson that runs on a check-in should do the trick. Plus you get versioning and rollbacks along with it.
With "Central Management Servers" feature of SQL Server 2008, what you can do is to add those three servers into one group and then run a single alter procedure script against these three servers.

How to run a stored procedure every day in SQL Server Express Edition?

How is it possible to run a stored procedure at a particular time every day in SQL Server Express Edition?
Notes:
This is needed to truncate an audit table
An alternative would be to modify the insert query but this is probably less efficient
SQL Server Express Edition does not have the SQL Server Agent
Related Questions:
How can I schedule a daily backup with SQl Server Express?
Scheduled run of stored procedure on SQL Server
Since SQL Server express does not come with SQL Agent, you can use the Windows scheduler to run a SQLCMD with a stored proc or a SQL script.
http://msdn.microsoft.com/en-us/library/ms162773.aspx
I found the following mechanism worked for me.
USE Master
GO
IF EXISTS( SELECT *
FROM sys.objects
WHERE object_id = OBJECT_ID(N'[dbo].[MyBackgroundTask]')
AND type in (N'P', N'PC'))
DROP PROCEDURE [dbo].[MyBackgroundTask]
GO
CREATE PROCEDURE MyBackgroundTask
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- The interval between cleanup attempts
declare #timeToRun nvarchar(50)
set #timeToRun = '03:33:33'
while 1 = 1
begin
waitfor time #timeToRun
begin
execute [MyDatabaseName].[dbo].[MyDatabaseStoredProcedure];
end
end
END
GO
-- Run the procedure when the master database starts.
sp_procoption #ProcName = 'MyBackgroundTask',
#OptionName = 'startup',
#OptionValue = 'on'
GO
Some notes:
It is worth writing an audit entry somewhere so that you can see that the query actually ran.
The server needs rebooting once to ensure that the script runs the first time.
Create a scheduled task that calls "C:\YourDirNameHere\TaskScript.vbs" on startup. VBScript should perform repeated task execution (in this example, it's a 15 minute loop)
Via command line (must run cmd.exe as administrator):
schtasks.exe /create /tn "TaskNameHere" /tr "\"C:\YourDirNameHere\TaskScript.vbs\" " /sc ONSTARTUP
Example TaskScript.vbs: This executes your custom SQL script silently using RunSQLScript.bat
Do While 1
WScript.Sleep(60000*15)
Set WshShell = CreateObject("WScript.Shell")
WshShell.RUN "cmd /c C:\YourDirNameHere\RunSQLScript.bat C:\YourDirNameHere\Some_TSQL_Script.sql", 0
Loop
RunSQLScript.bat: This uses sqlcmd to call the database instance and execute the SQL script
#echo off
sqlcmd -S .\SQLEXPRESS -i %1
If you are using Express Edition, you will need to use the Windows Scheduler or the application connecting to the server in some way.
You would use the scheduler to run sqlcmd. Here are some instructions for getting the sqlcmd working with express edition.
SQL Scheduler from http://www.lazycoding.com/products.aspx
Free and simple
Supports all versions of SQL Server 2000, 2005, and 2008
Supports unlimited SQL Server instances with an unlimited number of jobs.
Allows to easily schedule SQL Server maintenance tasks: backups, index rebuilds, integrity checks, etc.
Runs as Windows Service
Email notifications on job success and failure
Since another similar question was asked, and will likely be closed as a duplicate of this one, and there are many options not mentioned in the answers already present here...
Since you are using SQL Express you can't use SQL Server Agent. However there are many alternatives, all of which you can schedule using AT or Windows Task Scheduler depending on your operating system:
VBScript
C# command line app
batch file with SQLCMD
PowerShell
All of these languages/tools (and many others) have the capacity to connect to SQL Server and execute a stored procedure. You can also try these Agent replacements:
SQLScheduler
Express Agent
Standalone SQL Agent (beta)
The easiest way I have found to tackle this issue is to create a query that executes the stored procedure then save it. The query should look similar to this one below.
use [database name]
exec storedproc.sql
Then create a batch file with something similar to the code below in it.
sqlcmd -S servername\SQLExpress -i c:\expressmaint.sql
Then have the task scheduler execute the batch as often as you like
Another approach to scheduling in SQL Express is to use Service Broker Conversation Timers. To run a stored procedure periodically, which you can use to bootstrap a custom scheduler.
See eg Scheduling Jobs in SQL Server Express
You could use Task Scheduler to fire a simple console app that would execute the Sql statement.
As you have correctly noted, without the agent process, you will need something else external to the server, perhaps a service you write and install or Windows scheduler.
Note that with an Express installation for a local application, it is possible that the machine may not be on at the time you want to truncate the table (say you set it to truncate every night at midnight, but the user never has his machine on).
So your scheduled task is never run and your audit log gets out of control (this is a problem with SQL Server Agent as well, but one would assume that a real server would be running non-stop). A better strategy if this situation fits yours might be to have the application do it on demand when it detects that it has been more than X days since truncation or whatever your operation is.
Another thing to look at is if you are talking about a Web Application, there might be time when the application is loaded, and the operation could be done when that event fires.
As mentioned in the comment, there is sp_procoption - this could allow your SP to run each time the engine is started - the drawbacks with this method are that for long-running instances, there might be a long time between calls, and it still has issues if the engine is not running at the times you need the operation to be done.
Our company also use SQLEXPRESS and there is no SQL Agent.
Since there is no marked answer as "right" and all the solutions are quite complex I'll share what I did there. May be its really bad, but it worked great to me.
I've chosen operations of Insertion (people do) to a table that got closely the same time range i needed and made a trigger "ON INSERT" that applies needed function.