Most people who use SQL Server, know about the convention of adding GO
to the end of each batch of T-SQL statements. But perhaps less commonly known, is that you can also add an integer after GO
to specify how many times the batch should run.
Example 1 – Basic Usage
Here’s an example of how it works.
SELECT GETDATE() AS DateTime; GO 3
Result:
+-------------------------+ | DateTime | |-------------------------| | 2020-01-08 09:26:31.663 | +-------------------------+ Beginning execution loop +-------------------------+ | DateTime | |-------------------------| | 2020-01-08 09:26:31.663 | +-------------------------+ Beginning execution loop +-------------------------+ | DateTime | |-------------------------| | 2020-01-08 09:26:31.663 | +-------------------------+ Beginning execution loop Time: 0.578s
I specified GO 3
which resulted in the query running three times. I also got the words “Beginning execution loop” each time the query ran.
I get different results for this query depending on which tool I used to run the query. These are the results I got while using the mssql-cli command line tool. The fractional seconds are all the same. But when I used Azure Data Studio, the fractional seconds incremented.
Example 2 – Print Date/Time
Here’s an example that I ran using Azure Data Studio showing the fractional seconds incrementing.
DECLARE @theTime time(7) = GETDATE(); PRINT @theTime; GO 5
Result:
Started executing query at Line 4 Beginning execution loop 09:31:40.6100000 09:31:40.6166667 09:31:40.6200000 09:31:40.6233333 09:31:40.6266667 Batch execution completed 5 times... Total execution time: 00:00:00.022
Example 3 – A Database Example
Here’s an example that inserts data into a database.
CREATE TABLE LoopTest ( LoopTestId uniqueidentifier NOT NULL DEFAULT NEWID(), InsertDate datetime2(7) NOT NULL DEFAULT GETDATE() ); GO INSERT LoopTest (LoopTestId, InsertDate) VALUES (DEFAULT, DEFAULT); GO 20 SELECT * FROM LoopTest; GO
Result:
+--------------------------------------+-----------------------------+ | LoopTestId | InsertDate | |--------------------------------------+-----------------------------| | d6eda0a2-710d-467e-a4cf-41602e161851 | 2020-01-08 09:37:38.4733333 | | 0d8b3622-946f-4dce-816e-6123516da4e4 | 2020-01-08 09:37:38.4833333 | | b3ac2482-7304-4846-a258-5dc51b2623f9 | 2020-01-08 09:37:38.4866667 | | 1744836e-6af6-40c8-ab7e-98ca88e8ac1b | 2020-01-08 09:37:38.5000000 | | 91c4858c-0c31-4d99-aba5-3a70424239fd | 2020-01-08 09:37:38.5066667 | | f8b3de8b-7dd1-46c3-a7a8-b1af711d676d | 2020-01-08 09:37:38.5133333 | | 306467d8-2e5b-4046-8102-a33f6906b41d | 2020-01-08 09:37:38.5233333 | | 6cf93d79-5921-498e-ab14-55782284dc12 | 2020-01-08 09:37:38.5333333 | | 7bb99e3b-d174-47eb-81b3-46b49982eaad | 2020-01-08 09:37:38.5500000 | | c788d046-0c6c-4a2b-b3f1-3415470bf723 | 2020-01-08 09:37:38.5566667 | | 52bb8951-8e71-46ac-ab98-1e261751dc5b | 2020-01-08 09:37:38.5600000 | | 3a061055-0b1e-405c-aa13-480cdde8291c | 2020-01-08 09:37:38.5666667 | | 1cabaf44-ac85-4bcf-8fee-7d349cb56561 | 2020-01-08 09:37:38.5700000 | | 0cb3a690-66e9-458d-8c27-b0f44af4211d | 2020-01-08 09:37:38.5766667 | | 19719223-eb9f-4477-82cc-e60995e0dcee | 2020-01-08 09:37:38.5800000 | | 6da2484d-68c7-43f4-8ffc-968545974a42 | 2020-01-08 09:37:38.5833333 | | d644bbed-047f-49ac-98c4-e032bdb4add3 | 2020-01-08 09:37:38.5900000 | | 2c215900-0fd8-4889-8115-2a904ac72a61 | 2020-01-08 09:37:38.5933333 | | 01ccc184-3657-4298-98a7-b31e158a56e8 | 2020-01-08 09:37:38.5933333 | | 9270036f-8821-45c8-aef5-30aec2d4f4b4 | 2020-01-08 09:37:38.6000000 | +--------------------------------------+-----------------------------+
In this case, both columns are being inserted with DEFAULT
, which results in each column being populated with its default value (which I also specify). The first column has a default value of NEWID()
, a function that generates a GUID. The second column has a default of GETDATE()
, which results in the current date and time.