How to set morethan max size charecters in NVARCHAR(MAX),sql Server2005 - sql

I am using
declare #insertsql nvarchar(MAX)
--above #insertsql for sp_executesql takes only nvarchar as input
set #insertsql='--i am giving More than 10000 characters here -----'
EXEC sp_executesql #insertsql, N'#inXMLRequest XML OUTPUT', #inXMLRequest OUTPUT
how to insert morethan 10000 charecters in NVARCHAR(MAX) in sql server2005
can any one help please
Thanks in advance

This has happened to me when I use inline SQL statements instead of stored procs.
If you are hitting that ceiling, you may want to consider moving to stored procs.

The parameter that you use for the command to run in sp_executesql (#insertsql in your case) is NVARCHAR(4000) not NVARCHAR(MAX) so you are limited to a 4000 character dynamic SQL command.
If you are running out of space in the variable, you'll need to do some code re-factoring.

Thanks to All,
i got the answer
Insted of using SP_Executesql directly we Executing nvarchar variable
Above we Are preparing #insertsql nvarchar variable morethan 8000 characters and it is giving to sp_executesql like this
EXEC sp_executesql #insertsql, N'#inXMLRequest XML OUTPUT',#inXMLRequest OUTPUT
insted of above query replaced with below query
Exec ('DeClare #inXMLRequest XML SET #inXMLRequest='------above 8000 characters---')
Finally we will execute that nvarchar string and get out put

sp_executesql will accept an NVARCHAR(MAX) which can be longer than 4000, only it cannot be assigned all at once. It needs to be assigned 4000 characters in a single assignment statement and then appended as shown here:
declare #strSQL nvarchar(max)
--#strSQL + REPLICATE(' ', 5000)+' ''ERROR!'''
--exec sp_executesql #strSQL
SET #strSQL = N'SELECT'+ REPLICATE(' ', 3000)
SET #strSQL = #strSQL + REPLICATE(' ', 3000)+' ''This works'''
exec sp_executesql #strSQL
select LEN (#strSQL)

Related

##ROWCOUNT shows as 0 when deleting using dynamic query SQL

I am facing a trouble when using dynamic query and when trying to get the number of deleted records using ##ROWCOUNT
Here is my QUery
declare #query nvarchar(max)='delete from '+ #table_name + ' where kfh_id=' + cast(#kfh_id as varchar)
--print #query
exec (#query)
print #query
insert into tbl_cleanup_log (tablename,kfh_id,rows_affected,remark,deletiontime)
values(#table_name,#kfh_id,##ROWCOUNT,#query,getdate())
Here after the dyanimic delete query (inside my cursor) I am trying to store the number of deleted records into another table using ##ROWCOUNT. But it shows as 0.
I didnt understand what I did wrong.
My SQL version is 2012
##ROWCOUNT is working correctly. From the documentation:
Returns the number of rows affected by the last statement. If the number of rows is more than 2 billion, use ROWCOUNT_BIG.
The prior statement to the statement you use ##ROWCOUNT in is print #query and that returns no rows, and hence ##ROWCOUNT returns 0.
To fix this I would suggest PRINTing your dynamic statement first. Also you need to fix your dynamic statement so it isn't open to injection. Don't use the syntax EXEC (#SQL), use a parametrised call to sys.sp_executesql and ensure you properly delimit identify your dynamic object with QUOTENAME:
DECLARE #table_name sysname,
#kfh_id int; --Guessed data type
DECLARE #query nvarchar(MAX) = N'delete from dbo.' + QUOTENAME(#table_name) + N' where kfh_id= #kfh_id;'; --Schema is guessed.
PRINT #query;
EXEC sys.sp_executesql #query, N'#kfh_id int', #kfh_id; --Reminder, guessed #kfh_id data type
INSERT INTO tbl_cleanup_log (tablename,
kfh_id,
rows_affected,
remark,
deletiontime)
VALUES (#table_name, #kfh_id, ##ROWCOUNT, #query, GETDATE());
##ROWCOUNT should be the used immediately after statement, here the PRINT is between and it's changing the result:
DECLARE #row_cnt INT;
EXEC (#query);
SET #row_cnt = ##ROWCOUNT;
print #query;
insert into tbl_cleanup_log (tablename,kfh_id,rows_affected,remark,deletiontime)
values(#table_name,#kfh_id,#row_cnt ,#query,getdate());

EXEC sp_executesql will work with Integers but not VarChars

I'm using EXEC sp_executesql for a dynamic query in SQL Server 2017.
I've tried various testing scenarios, and I can get results in my query (for other parameters) as long as the values passed in are Integers. So, that means, Location and Department testing works. However, I can't figure out if there's something I need to do differently for when I'm sending a NVARCHAR or DateTime.
Here's my stored procedure, with the NVARCHAR param. Do you see anything I'm doing wrong?
(
#tktitle NVARCHAR(200)
)
AS
BEGIN
Declare #SQL NVARCHAR(MAX)
Set #SQL = 'SELECT timekeep.tkinit, timekeep.tkfirst, timekeep.tklast,
timekeep.tkemdate, timekeep.tktitle, timekeep.tkloc, timekeep.tkdept
FROM abc.xyz'
IF #tktitle IS NOT NULL
Select #SQL = #SQL + 'AND ([tktitle] = #tktitle)'
EXEC sp_executesql #SQL, N'#tktitle varchar', #tktitle
END
I can identify at least three issues:
You need to specify a length for varchar when passing it as a parameter.
You also need a space before the AND and the AND should be a WHERE.
You need to assign the parameter in the execute call.
So:
IF #tktitle IS NOT NULL
Select #SQL = #SQL + ' WHERE ([tktitle] = #tktitle)';
-------------------------^ separator
EXEC sp_executesql #SQL, N'#tktitle varchar(200)', #tktitle=#tktitle;

EXEC sp_executesql #sql limitation

I am having problem with executing dynamic SQL Server code.
I have an insert into temp table and the number of chars is more than 4000.
I tried to split into two variables and then concatenated them but problem is
EXEC sp_executesql #sql,
N'#DimStartDate int, #DimEndDate bigint',
#DimStartDate, #DimEndDate;
I found on net that EXEC(#sql1+#sql2) is solution but I really need input parameters. How can I solve this?
I have dealt with a similar issue before, like below. Basically you need to separate your main query into pieces, then combine them in the end and use sp_EXECUTESQL to run your dynamic query.
DECLARE #SQL_Part1 varchar(4000);
DECLARE #SQL_Part2 varchar(4000);
DECLARE #SQL_Part3 varchar(4000);
DECLARE #SQL_Part4 varchar(4000);
DECLARE #SQL_Part5 varchar(4000);
DECLARE #SQL_FullQuery nvarchar(MAX);
.. set your queries...
SET #SQL_FullQuery = CAST(#SQL_Part1 + #SQL_Part2 + #SQL_Part3 + #SQL_Part4 + #SQL_Part5 as nvarchar(MAX));
EXEC sp_EXECUTESQL #SQL_FullQuery;
I have had no problem with sp_executesql on strings very long strings. You simply need to declare the query to be long enough:
declare #sql nvarchar(max);
You can have an error inserting into a table if the row length is too long for the table. That would have nothing to do with the dynamic statement. The maximum length of a row is limited in SQL Server -- although you can use long strings and blobs to work around that.
Not sure exactly where the problem is. SQL Server will happily execute more than 4,000 characters, so your SQL must be getting truncated somewhere else. Here is an example where I've manually built up a batch that is more than 4,000 characters total so you can see that all three SELECT statements run and if you copy and paste the middle result you'll see it has the y at the end:
DECLARE #sql nvarchar(max) = N'SELECT 1;'
+ N'SELECT ''' + CONVERT(nvarchar(max), REPLICATE('x', 4096)) + N'y'';';
+ N'SELECT 2;';
EXEC sys.sp_executesql #sql;
Results:

Using a Variable in OPENROWSET Query

I'm having trouble with this query:
SELECT *
FROM OPENROWSET(
'SQLNCLI',
'DRIVER={SQL Server};',
'EXEC dbo.sProc1 #ID = ' + #id
)
Gives an error:
Incorrect syntax near '+'.
Anyone know why I'm getting this error?
As suggested by Scott , you cannot use expressions in OPENROWSET.Try creating a dynamic sql to pass the parameters
Declare #ID int
Declare #sql nvarchar(max)
Set #ID=1
Set #sql='SELECT *
FROM OPENROWSET(
''SQLNCLI'',
''DRIVER={SQL Server};'',
''EXEC dbo.usp_SO #ID =' + convert(varchar(10),#ID) + ''')'
-- Print #sql
Exec(#sql)
OPENROWSET requires string literals, not expressions. It's complaining about the plus sign, becaue it doesn't expect anything more than a string literal and you follewed the string literal with an operator.
See http://msdn.microsoft.com/en-us/library/ms190312.aspx which states:
'query'
Is a string constant sent to and executed by the provider...
Declare #Route VARCHAR(200)
Declare #sql nvarchar(max)
Set #Route='C:\OCRevisiones.xlsx;'
Set #sql='SELECT * INTO FFFF
FROM OPENROWSET(
''Microsoft.ACE.OLEDB.12.0'',
''Excel 12.0;HDR=YES;Database=' + #Route + ''',
''SELECT * FROM [Sheet1$]'')'
Print #sql
--Exec(#sql)
If you need parameters you can also use sp_executesql:
BEGIN
DECLARE
#p_path varchar(200)='D:\Sample\test.xml',
#v_xmlfile xml,
#v_sql nvarchar(1000)
SET #v_sql=N'select #v_xmlfile= CONVERT(XML, BulkColumn) FROM
OPENROWSET(BULK '''+#p_path+''', SINGLE_BLOB) AS x;'
EXEC sp_executesql #v_sql,N'#v_xmlfile xml output',#v_xmlfile output;
SELECT #v_xmlfile
END
For what it is worth..
The reason we use openrowset rather than a straight linked server query is that the processing for a linked server query happens on the local server. (Slow and often brings most of the table back)
Yes we can do the string concatination as above.
A different option where you have ease of syntax and the power of parameters.
Create a stored proc on the remote box, that proc has all the parameters you need.
Call the stored proc from with a standard linked server query (same perf or better than the above soultion and significantly easier to code with.
e.g. linkedservername.database.dbo.myproc 123,'abc','someparam',getdate()
Just an option....
You can use Char(39) instead of '
set #lcSql= 'SELECT production_pbook_uq,variety_uq,color_uq,grade_uq,diff_qty
FROM OPENROWSET("SQLNCLI",
"Server=.;Trusted_Connection=yes;",
"EXEC serversql.dbo.sp_flower_production_varieties_consolidated #lcproduction_pbook_uq='+char(39)+#lcWo_uq+char(39)+', #lcproduct_piso_uq ='+char(39)+#lcpiso_uq+char(39)+'")'
+'where diff_qty>0'
print #lcSql

SQL with table name as parameter and query longer than 4000 characters

I am trying to write a stored procedure that takes a table name as a parameter. Yes I already know this is a security vulnerability, but this is an internal stored proc that doesn't face typical risks of SQL Injection.
What I have so far is something like the following:
CREATE PROCEDURE [dbo].[myprocedure]
#tableName sysname
AS
DECLARE #cmd nvarchar(4000)
SET #cmd = N' Select blah blah from ' + #tableName
EXEC (#cmd)
GO
The query will work in theory, but my problem is that my query is longer than 4000 characters. Is there another way to use #tableName in a cmd variable longer than 4000 characters (which is nvarchar's max)?
If you use SQL Server >= 2005, try replacing nvarchar(4000) with nvarchar(MAX).
DECLARE #cmd NVARCHAR(MAX);
Extract some of your logic into views or user defined functions.
Use
DECLARE #cmd VARCHAR(8000)
instead of DECLARE #cmd NVARCHAR(MAX);
NVARCHAR(MAX) ALLOWS ONLY 4000 CHARACTERS.