In Windows 10, it seems that all RAISERROR WITH NOWAIT messages called from sqlcmd are now hidden in the command prompt until the batch is complete:
> sqlcmd -Q "raiserror('Test message', 10, 1) with nowait; waitfor delay '00:00:05'" -b -r1
(no output to console until waitfor is finished)
Compare this to the same command run from Windows 2008 R2:
> sqlcmd -Q "raiserror('Test message', 10, 1) with nowait; waitfor delay '00:00:05'" -b -r1
Test message
(immediate output)
In the above example, you can see the message even though the batch hasn't completed.
Is there a configuration setting in Windows 10 that will bring back this functionality? I have legacy batch files that depend on WITH NOWAIT to show progression.
This occurs because sqlcmd11 (not sure about higher) does not honor RAISERROR WITH NOWAIT. It does not seem to have anything to do with the underlying OS.
Here's a link to a stackoverflow post with some possible work-arounds.
Related
How do I get unbuffered output when using sqlcmd
Lets say I have a file:
while (1=1)
begin
print '------------------------------------------------------'
select NOW=getdate(), DB=db_name()
waitfor delay '00:00:01'
end
go
And I execute the above file with:
sqlcmd -Usa -S srvName -P passwd -i xxx.sql
I would expect ouput every second!
But it takes about a minute or two before anything is returned
So if I want to "report" anything in the SQL batch I can't tdo that???
Is there anyway I can change this behaviour?
NOTE 1: The OS I'll be using is Linux, but when testing, it was the same behaviour on both platforms
NOTE 2: I'm used to Sybase and isql, which is "unbuffered"
I have the following batch file and SQL script that runs several .sql files. Is there a way to log any errors and continue with script?
myautosql.sql
PRINT 'Starting...'
--:On Error exit
:r SQLQuery10.sql
:r SQLQuery20.sql
:r SQLQuery30.sql
PRINT 'Completed normally on ' + (CONVERT( VARCHAR(24), GETDATE(), 101))
GO
myautosql.bat
SQLCMD -E -d rstestdb1 -i myautosql.sql
PAUSE
When I intentionally raiseerror in the SQLQuery20.sql file the batch program stops. Is there a way for it to log the error and continue with script?
When you raiserror, the 2nd parameter severity dictates whether the query will continue to run or not. A severity of 0-10 are informational (no error is raised), 11-19 are non fatal errors, 20-25 will raise the error and then immediately terminate your connection to the database server. You must be a sysadmin to use a severity from 19-25.
I think this simulates what you are trying to do.
auto.sql
PRINT 'Starting...'
:r 1.sql
:r 2.sql
PRINT 'Completed normally on ' + (CONVERT( VARCHAR(24), GETDATE(), 101))
1.sql
select 1 as value
raiserror ('This will not stop execution', 11, 1)
select 2 as value
2.sql
select 3 as value
raiserror ('This is an information message, not an error', 10, 1)
select 4 as value
Then you run the following command to capture the query output to output.txt and informational/error messages to error.txt:
sqlcmd -E -d tempdb -i auto.sql -r1 >output.txt 2>error.txt
-r1 tells sqlcmd to redirect informational/error messages to STDERR.
>output.txt redirects STDOUT from the queries (including affected row counts) to a file called output.txt.
2>error.txt redirects STDERR to a file called error.txt.
Here are the two files from the above script:
output.txt
value
-----------
1
(1 rows affected)
value
-----------
2
(1 rows affected)
value
-----------
3
(1 rows affected)
value
-----------
4
(1 rows affected)
error.txt
Starting...
Msg 50000, Level 11, State 1, Server NAME, Line 4
This will not stop execution
This is an information message, not an error
Completed normally on 02/27/2020
HTH
In SQL Server 2016, I am executing a SQL script through SQLCMD like this:
SQLCMD -H XXXXXX,1433 -U username -P password -d mydatabase
-v varMDF="testing" -i "Script.sql" -o "DATA.txt"
and in Script.sql, I want to echo some text to the console, just to see the progress. I have a while loop in the script and executing the command
echo I am in sql script
as shown here:
OPEN tab_cursor
FETCH NEXT FROM tab_cursor INTO #tablename
WHILE ##FETCH_STATUS = 0
BEGIN
!!echo i am in sql script
PRINT #tablename
FETCH NEXT FROM tab_cursor INTO #tablename
END
CLOSE tab_cursor
DEALLOCATE tab_cursor
The problem is, it display the line "i am in sql script" only once in console but I could see many entries for tablename in my output file. Please help to solve this issue or suggest if there is any other way to do this.
Thanks
I would try the following solutions in order:
1) Look into BCP; it might allow you to see what you are doing much more effectively, and depending on the size of your output file it may be significantly faster. (1b : look into SSIS, even though it's a huge pain)
2) putting a SQLCMD execution inside of Script.sql that did the data push to the file, and having the PRINT statement work as normal without a -o. (NOTE: If this is a Complicated Stored Procedure, why aren't you writing a Complicated Stored Procedure?)
3) Monkeying with server monitoring and profiler. This would be for debugging purposes only, if that's why you need the output.
Generally, it sounds to me like the source of your problem is that you're using the wrong tool for the job. If you want lots of output from SQLCMD on process status, you're probably using it where you should be using BCP, which is designed for doing exports programmatically. SQLCMD isn't all that great an interface for running complicated scripts, in my experience; it needs fire-and-forget.
Basically I have a batch file which calls a SQL Server 2008 R2 stored procedure that interogates that DB for fragmentated tables over 5% fragmented and outputs the report to a text file.
The batch file is set as a Task Scheduler job to run overnight.
In Task Scheduler If I right click the task and select run immediately it executes fine, the script is in turn run on SQL Server and the output is redirected to a text file, everything is working as desired at this point, the problem is when I automate it to trigger overnight.
set local
REM Preparing Timestamp Information
set year=%date:~6,4%
set month=%date:~3,2%
set day=%date:~0,2%
set hour=%time:~0,2%
REM Replace leading space with zero
if “%hour:~0,1%” ==” ” set hour=0%hour:~1,1%
set minute=%time:~3,2%
set seconds=%time:~6,2%
set FILENAMEANDPATH= c:\DBMaintenanceLogs\SP_InspectorLog_%day%-%month%-%year%_%hour%-%minute%-%seconds%.log
sqlcmd -S .\SQLEXPRESS -E -Q "EXEC sp_DBIndexFragmentationInspector #IndexFragmentationPercentage=5" -d MyDBName -o %FILENAMEANDPATH%
The problem is that when left alone the Task Scheduler job will not run and the task says completed successfully with return code 255?
The Task is set to run using the system administrator account.
P.S. The Stored Procedure is:
USE [MyDBName]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[sp_DBIndexFragmentationInspector]
#IndexFragmentationPercentage INT
AS
BEGIN
SELECT
OBJECT_NAME(A.[object_id]) as 'TableName',
B.[name] as 'IndexName',
A.[index_type_desc],
A.[avg_fragmentation_in_percent]
FROM
sys.dm_db_index_physical_stats(db_id(),NULL,NULL,NULL,'LIMITED') A
INNER JOIN
sys.indexes B ON A.[object_id] = B.[object_id] and A.index_id = B.index_id
where [avg_fragmentation_in_percent] > #IndexFragmentationPercentage
order by TableName
END
I've been confronted with exactly the same error. For me, the solution was to add exit 0 at the end of the script. I don't understand why but it worked.
I am calling an SQL Server script on a batch file, but I need get the error(when the script fail) in the batch file, what can I do?
This is the batch file:
sqlcmd -S HOST -U User -P password -i test.sql
echo %errorlevel%
and this is the Script File(Test.sql):
USE TrainingSitecore_Web
go
SELECT * FROM items
go
RAISERROR ('This is a test Error.',-- Message text.
16,-- Severity.
1 -- State.
);
Make sense?
It can be done using -r parameter:
Example:
sqlcmd -Q "select 1 as a; select 1/0 as b" -E -r1 1> NUL
-r[ 0 | 1] msgs to stderr
Redirects the error message output to the screen (stderr). If you do
not specify a parameter or if you specify 0, only error messages that
have a severity level of 11 or higher are redirected. If you specify
1, all error message output including PRINT is redirected. Has no
effect if you use -o. By default, messages are sent to stdout.
MSDN for more