sp_add_jobstep is well documented here. I understand parameter @command
is type NVARCHAR(MAX)
.
I am creating a SQL Agent Job using a Stored Procedure. Passing the value for @command
parameter via a variable. I am getting truncated at 4000 character.
My variable is also declared as NVARCHAR(MAX)
Any workaround to add more than 4000 characters in @command
parameter?
2 Answers 2
'This'
is a varchar
string.
N'This'
is an nvarchar
string.
I'll guess that, after @tblUpdateStats_List
, the remainder of your string was more than 4000 characters.
I did some experiments (in SQL 2016), and it looks like when a varchar
string is implicitly converted to nvarchar
, it is converted to nvarchar(4000)
, not nvarchar(MAX)
.
I ran the following query:
DECLARE @myNVar NVARCHAR(MAX);
SET @myNVar = 'ABCDEFG';
SET @myNVar = 'QQQ' + REPLICATE(@myNVar, 1000)
+<literal>
+'QQQ';
SELECT LEN(@myNVar), SUBSTRING(@myNVar, 6990, 25), RIGHT(@myNVar, 20);
With <literal>
initially being an nvarchar string constructed as follows:
- The character 'Z', repeated 3 times
- the character 'z', repeated 1027 times
- the character 'X', repeated 3 times
- EOL
- The resulting string copied, and pasted in 3 more times (wit the fourth EOL removed)
This string was 4,138 characters long (on Windows, where EOL is CR+LF), so the total string length should have been 3 + 7000 + 4138 + 3, or 11,144 characters
When run with the literal as an nvarchar
string, got the following results:
11144 ABCDEFGABCDEFGZZZzzzzzzzz zzzzzzzzzzzzzzXXXQQQ
So, correct length, and expected values at end of replicated string, at start of literal, and at end of literal.
Then, I changed the literal to a varchar
string, and got this:
11006 ABCDEFGABCDEFGZZZzzzzzzzz zzzzzzzzzzzzzzzzzQQQ
So, length shows 3 +たす 7000 +たす 4000 +たす 3 =わ 11006 - what we'd expect if the varchar value was truncated down to just 4,000 characters. And, we don't see XXX
before the final QQQ
, also as we'd expect under these circumstances.
FYI - If I CAST
the varchar
literal to nvarchar(MAX)
, my results went back to the first ones, so an explicit cast avoids this problem.
-
Thank you. I agree with your comment about implicit conversion. My problem was part of my string was
NVARCHAR
and part wasVARCHAR
. I started withN
then I had many variables in the string where I did not putN'
. Once I addedN
in front of every string it did work for me. After@tblUpdateStats_List
I have many more strings separated by variables.SqlWorldWide– SqlWorldWide2017年05月31日 23:37:29 +00:00Commented May 31, 2017 at 23:37 -
I may have been making this mistake of mixing types in a string for EXEC() or for sp_executesql . I hadn't identified some combinations as safe and some not, but my workaround for it has been to use just one long string which contains token marker terms like @{explicit_integer} and '@{explicit_string}', into @template nvarchar(max), then, REPLACE() each of the tokens with the required value, instead of inserting by adding strings together.Robert Carnegie– Robert Carnegie2017年06月01日 23:20:41 +00:00Commented Jun 1, 2017 at 23:20
I had to add N
before every termination of string. What I mean by that?
Before I did not had N
after @dbName
and @tblUpdateStats_List
variables.
DECLARE @command2 NVARCHAR(MAX)
SET @command2 =N'SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
USE [' + @dbName +']
INSERT INTO [DBA].[dbo].['+@tblUpdateStats_List+'] ....................
Added N
after @dbName
and @tblUpdateStats_List
and now I can pass more than 4000 character to @command
parameter.
DECLARE @command2 NVARCHAR(MAX)
SET @command2 =N'SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
USE [' + @dbName +N']
INSERT INTO [DBA].[dbo].['+@tblUpdateStats_List+N']..................
DECLARE @command1 NVARCHAR(MAX)
then ` @command=@command1` .