The stored procedure contains 2 dml statements,ie 2 update queries.
There is a need of executing the 2nd statement only after the complete exection of first query.
CREATE PROCEDURE usp_pn
AS
BEGIN
Update [db1].dbo.[table1]
SET
[date1] = DateDiff(MI,[Ar_DateTime],[Departure_DateTime])
Update [db1].dbo.[table1]
SET
[InMinutes] = [date1]+some_calculation
END
GO
here i want to ensure the 2nd update has to run only after the first update completed
So can i write the stored procedure as shown above or is there any modification required??#
Please sugest
I just want to know the execution details:that is there are more than one dml statements in an sp then are these 2 going to run parallely or run one after another..
It might be a basic question but just want to know some thoughts...
Thanks
The statements always run sequentially.
Individual statements can be parallelised but SQL Server will never run different statements in the same batch in parallel.
A great Remus Rusanu article discussing this (and more) is Understanding how SQL Server executes a query
This should settle the often asked question whether statements in a
SQL batch (=> request => task => worker) can execute in parallel: no,
as they are executed on a single thread (=> worker) then each
statement must complete before the next one starts.
For the specific example in your question though (perhaps this is an over simplified example?) I would use a single statement
UPDATE [db1].dbo.[table1]
SET [date1] = DateDiff(MI, [Ar_DateTime], [Departure_DateTime]),
[InMinutes] = DateDiff(MI, [Ar_DateTime], [Departure_DateTime]) + some_calculation
Related
I have two TSQL EXEC statements
EXECUTE (N'MyDynamicallyGeneratedStoredProcedure') -- return 0 on success
SELECT #errCode = ##ERROR ;
IF (#errCode = 0)
BEGIN
EXEC 'A Sql Statement using ##temptable created from first', #returnValue
END
How do I make the two EXEC's synchronous? ; Right now the second EXEC does not wait for the first EXECUTE to complete. I tried issuing a WaitFor Delay, It waits but the second EXEC statement is never returing back.
Thanks.
Update, Here is more info:
First execute creates a global temp table and populates it from a complex SELECT query.
Second EXEC is a CLR Stored Procedure that generates a dynamic SP, based on the variables from recently created and populated Global Temp table.
Now the second EXEC, complains that the Global Temp table is not found.
Update 2, Found the issue (And its me!!)
GBN (and others) was point blank on the answer. EXEC IS synchronous. The problem? My understanding of the problem itself.. I had mentioned
EXECUTE (N'MyDynamicallyGeneratedStoredProcedure') -- return 0 on success
It should have been:
1(a) EXECUTE (N'CreateMyDynamicStoredProcedure') -- return 0 on success
1(b) EXECUTE (N'MyDynamicStoredProcedure') -- return 0 on success
I missed that 1(b) was actually executed somewhere else and after step (2) .
(I should go get a life!!)
EXECUTE is sychronous. The 2nd one runs after the 1st one. Always.
Do you have multiple connections running the same code? You are using a global temp table that will be visible to all connections so it may look like asyncc execution...
As gbn's answer has pointed out, EXECUTE is synchronous.
The problem might be that your SQL Connection object within CRL stored procedure is not in the same context as your batch script. Your global temporary table should have been dropped after running EXECUTE (N'MyDynamicallyGeneratedStoredProcedure')
Make sure that you create your SQLConnection object by passing "context connection=true"
Here is the post answer where someone had a similar problem accessing temporary table since SQLConnection was not in the same connection context.
Accessing TSQL created #temp tables from CLR stored procedure. Is it possible?
If your second CRL stored procedure runs through a different connection, CRL sproc will not be able to access the global temp table since it should have been dropped.
Refer to this post on Global Temporary life cycle (when the gloal temp is dropped)
Deleting Global Temporary Tables (##tempTable) in SQL Server
Is there any possibility to run update at some specific point of time, but in different/parallel session? In the provided example I want some specific update to be run at the time when I run WAITFOR. Currently I have this WAITFOR block to have some time to switch to another SSMS (or other tool) window/tab and run update while it's waiting for 10 secs. Logically the only thing is needed to be done, is that transaction started at this point of time.
EXEC dbo.p_sync_from_accounts_ext_test #enable_snapshot_isolation = 1
, #run_update_flag = NULL
, #run_wait_for_10 = NULL
, #acc = #acc;
WAITFOR DELAY '00:00:10'; -- Execute update in parallel transaction
-- table update should be performed in that parallel transaction
EXEC dbo.p_finish_sync_attributes;
Yes, you can do it.
Method 1: loop-back linked server (linked server that points to your current server) that does not have DTC enabled. Call your SP from your linked server.
Methd 2: create an SQL Server Job and start the job programmatically.
Note that in the first case your update statement must be included in an SP. In the second case it is advisable but not necessary.
I have a stored procedure (simplified version) as below. In general it will push the pending items to email queue and update the status of those items to pushed. This stored procedure has been called in a 60 seconds interval.
ALTER PROCEDURE [dbo].[CreateEmailQueue]
AS
BEGIN
insert into EmailQueue
select *
from actionstatus
where actionstatus='Pending'
update actionstatus
set actionstatus = 'Pushed'
where actionstatus = 'Pending'
END
It works fine but I found one exception record. The exception's action status has been changed to "Pushed" but the record did not appear in the EmailQueue. I suspected that the action status record has been generated after the insert but before the update. But I am not 100% sure as I assume that SQL Server always execute a stored procedure in an isolation block so the data change won't affect the data set inside the execution. Could someone help explain the actual process inside the stored procedure, review this stored procedure and advise if it is OK, or it should be put in a transaction block? and, any performance or locking issue for doing this in transaction? Thanks for your input.
You must use transactins inside stored procedure. SQL Server don't generate transactions for stored procedures calls automatically. You can simply check it by execute code something like taht:
insert ...
--this will falls
select 1/0
Insertion will be done and than you'll have division by zero error
SQL Server Management Studio always inserts a GO command when I create a query using the right click "Script As" menu. Why? What does GO actually do?
It is a batch terminator, you can however change it to whatever you want
Since Management Studio 2005 it seems that you can use GO with an int parameter, like:
INSERT INTO mytable DEFAULT VALUES
GO 10
The above will insert 10 rows into mytable. Generally speaking, GO will execute the related sql commands n times.
The GO command isn't a Transact-SQL statement, but a special command recognized by several MS utilities including SQL Server Management Studio code editor.
The GO command is used to group SQL commands into batches which are sent to the server together. The commands included in the batch, that is, the set of commands since the last GO command or the start of the session, must be logically consistent. For example, you can't define a variable in one batch and then use it in another since the scope of the variable is limited to the batch in which it's defined.
For more information, see http://msdn.microsoft.com/en-us/library/ms188037.aspx.
GO is not a SQL keyword.
It's a batch separator used by client tools (like SSMS) to break the entire script up into batches
Answered before several times... example 1
Just to add to the existing answers, when you are creating views you must separate these commands into batches using go, otherwise you will get the error 'CREATE VIEW' must be the only statement in the batch. So, for example, you won't be able to execute the following sql script without go
create view MyView1 as
select Id,Name from table1
go
create view MyView2 as
select Id,Name from table1
go
select * from MyView1
select * from MyView2
Go means, whatever SQL statements are written before it and after any earlier GO, will go to SQL server for processing.
Select * from employees;
GO -- GO 1
update employees set empID=21 where empCode=123;
GO -- GO 2
In the above example, statements before GO 1 will go to sql sever in a batch and then any other statements before GO 2 will go to sql server in another batch. So as we see it has separated batches.
I use the GO keyword when I want a set of queries to get committed before heading on to the other queries.
One thing I can add is, when you have some variables declared before the GO command you will not be able to access those after the GO command. i.e
DECLARE #dt DateTime = GETDATE();
UPDATE MyTable SET UpdatedOn = #dt where mycondition = 'myvalue';
GO
-- Below query will raise an error saying the #dt is not declared.
UPDATE MySecondTable SET UpdatedOn = #dt where mycondition = 'myvalue'; -- Must declare the scalar variable "#dt".
GO
Update
I see, people requesting when to use the Go command, so I thought, I should add why I use the Go command in my queries.
When I have huge updates in the tables and I usually run these updates while going off from work (which means, I wouldn't be monitoring the queries), since it is convenient to come the next day and find the tables ready for other operations.
I use Go command when I need to run long operations and want to separate the queries and complete part of the transactions such as:
-- First Query
Update MyBigTable1 SET somecol1='someval1' where somecol2='someval2'
GO
-- Second Query
Update MyBigTable2 SET somecol1='someval1' where somecol2='someval2'
GO
-- Third Query
Update MyBigTable3 SET somecol1='someval1' where somecol2='someval2'
Executing above queries will individually commit the modifications without resulting in huge roll-back logs formation. Plus if something fails on third query, you know first 2 queries were properly executed and nothing would be rolled-back. So you do not need to spend more time updating/deleting the records again for the previously executed queries.
To sum it up in just one sentence, "I use the GO command as a check point as in the video games." If you fail after the check point (GO command), you do not need to start over, rather your game starts from the last check point.
Use herDatabase
GO ;
Code says to execute the instructions above the GO marker.
My default database is myDatabase, so instead of using myDatabase GO and makes current query to use herDatabase
One usage that I haven't seen listed is Error Resilience.
Since only the commands between two GOs are run at a time, that means a compile error in one command can be separated from others. Normally any compile errors in a batch cause the entire thing to not be executed.
exec do.Something
GO
sel from table
print 'here'
GO
print 'there'
In above, 'here' will not be printed because of the error in the 'sel' statement.
Now, adding a GO in the middle:
exec do.Something
GO
sel from table
GO
print 'here'
GO
print 'there'
You get an error for 'sel' as before, but 'here' does get output.
tldr; In most cases nowadays GO is mostly IMO optional. Using GO is best in LARGE transaction batches where you would have compiled many different scripts together in a large script and don't want errors where similar variables are used and so that parts of the transaction is committed to the server when desired instead of all of the script being rolled back due to an error.
LARGE TRANSACTION 1 --> Runs Successfully
GO; --> Is in the server
LARGE TRANSACTION 2 --> Runs Successfully
GO; --> Is in the server
LARGE TRANSACTION 3 --> Errors
GO; --> Without the other GO statements this would rollback Transaction 1 & 2
Not sure the best way to provide this SO wise however I do feel like what I've read so far doesn't really sum it all up and include an example that I've come across.
As stated many times before GO simply "commits" a batch of commands to the server.
I think understanding sessions also helps with understanding the necessity (or optionality) of the GO statement.
(This is where my technicality may fail but the community will point it out and we can make this answer better)
Typically developers are working in a single session and typically just executing simple statements to the database. In this scenario GO is optional and really...all one would do is throw it at the end of their statements.
Where it becomes more helpful is probably an option given by Jamshaid K. where you would have many large transactions that you would want committed in turn instead of all transactions being rolled back when one fails.
The other scenario where this also becomes helpful (which is the only other spot I've experienced it) is where many small transactions are compiled into one large script. For example
Dev 1 makes script 1
Dev 2 makes script 2
Dev 1 makes script 3
In order to deploy them a python script is written to combine the scripts so Script Master = script1 + script 2 + script 3.
GO statements would be required in the 3 scripts otherwise there could be errors where the scripts use conflicting variables or if script 3 fails the transactions from scripts 1 and 2 would be rolled back.
Now this process is probably archaic given current CI/CD solutions out there now but that would probably be another scenario where I could see GO being helpful/expected.
GO means asking SQL repeat this whatever number you add next to it. Just like saying in English; "Hey GO there 3 times.". Try below in SQL and the result will be rendering table 3 times.
SELECT * FROM Table
GO 3
It is a command to separate queries. If you are doing multiple selects it doesn't make a huge difference, the main use for me for example is when I am creating scripts and you need to create stored procedures and after give access or execute them. For example:
CREATE OR ALTER PROCEDURE dbo.select1
AS
BEGIN
SET NOCOUNT ON
SELECT 1
END
EXEC dbo.select1
This one it will create the stored procedure with everything on it, including the EXEC and it would end-up in a loop.
So that GO it will say that after end create the stored proc and after execute it.
CREATE OR ALTER PROCEDURE dbo.select1
AS
BEGIN
SET NOCOUNT ON
SELECT 1
END
GO
EXEC dbo.select1
What is the difference between ; and GO in stored procedure in SQL Server ?
Actually, if I have a stored procedure in SQL server and wanna to put t separate queries inside it which the first one just calculates number of records (count) and the second one selects some records based on some conditions, then what should I use between that two queries?
Go or ;
; just ends the statement.
GO is not a statement but a command to the server to commit the current batch to the Database. It creates a stop inside the transaction.
http://msdn.microsoft.com/en-us/library/ms188037.aspx
(Update, thanks for the comments):
GO is a statement intended for the Management studio as far as I know, maybe to other tools as well.
The semicolon separates queries, the GO command separates batches. (Also GO is not a T-SQL command, it's a command recognised by the sqlcmd and osql utilities and Management Studio.)
You can't use GO inside a stored procedure. If you would try, the definition of the procedure will end there, and the rest will be a separate batch.
A local variable has the scope of the batch, so after a GO command you can't use local variables declared before the GO command:
declare #test int
set #test = 42
GO
select #Test -- causes an error message as #Test is undefined
I know this thread is old but I thought these other uses/differences might be handy for other searches like myself regarding GO.
Anything after the GO will not wind up in your sproc because the GO will execute the CREATE/ALTER PROCEDURE command. For example, if you run this...
CREATE PROCEDURE X AS
SELECT 1 As X
GO
SELECT 2 As X
Then after running it you go back in to edit the procedure you will find that only the SELECT 1 As X is in there because the GO created the sproc and anything after it is assumed to be the next thing you are doing and not part of the sproc.
I'm surprised I haven't seen this mentioned much out there but the batch separator is not only specific to the program you are querying with but in the case of SSMS it is actually user editable! If I went into the settings and changed the batch separator from GO to XX then in my copy of SSMS, XX executes the batch not GO. So what would happen if I tried to execute a stored procedure that contained GO?
Think of GO as a way of telling SSMS to send whatever is above it to the server for execution. The server never receives the GO as that is just there to mark the end of a batch of command you want SSMS to send to the server.
If you have a scenario where you need to control execution flow in your stored procedure then you can use BEGIN TRANSACTION and COMMIT TRANSACTION for that and those are allowed in stored procedures.
GO is not a command to the server, it's the default batch separator for most of the client tools the MS supply. When the client tool encounters "GO" on a new line by itself, it sends whatever commands it has accumulated thus far to the server, and then starts over anew.
What this means is that any variables declared in one batch are not available in subsequent batches. And it also means that multi-line comments can't be placed around a "GO" command - because the server will see the first batch, and see an unterminated comment.
It marks the end of a batch in Query Analyzer and
therefore signals the end of a stored procedure definition in that batch.
As much as i know its not a part of sp.
GO isn't a TSQL command.
And ; just ends the statement.