What's the equivalent to sp_executesql of Sql Server in sybase.
I think exec() is what you're looking for. See http://infocenter.sybase.com/help/index.jsp?topic=/com.sybase.help.ase_15.0.commands/html/commands/commands56.htm.
#jasir: the limitation to 255 characters results from your procedure definition. Isn't possible to extend this limit by defining e.g. varchar(1024)?
ASE Refrence Manual 15.7 (http://infocenter.sybase.com/help/index.jsp?topic=/com.sybase.infocenter.dc36272.1572/html/commands/X30305.htm)
states for command execute:
string is a literal string containing part of a Transact-SQL command
to execute. There are no restrictions to the number of characters
supplied with the literal string.
However, sometimes a system on top of sybase (e.g. Kondor+, a product for financial markets uses ASE 15.x as DB) may set limits. In this Kondor+ it is not possible to use
exec( #SQLQuery)
in its so called OpenReport (a stored procedure), if the variable #SQLQuery exceeds 256 characters.
For older ASE, you can use this workaround:
There is stored procedure sp_remotesql.
You can use it to run query on local server too, you just have to local server to servers:
sp_addserver local, NULL, <servername>
Where <servername> is name of local server (from sql.ini).
You can add shortcut procedure for running sql:
create procedure sp_exec_dynsql #p_cmd varchar(255)
as
begin
exec sp_remotesql "local", #p_cmd
end
Unfortunatelly, you are limited to 255 characters in your sql.
Related
I have bunch of servers that I need their information such as servername and instance name and add all these information into a table in Server X. I am using sqlcmd to connect to server X, here is a simple code:
declare #servername varchar(30)
set #servername=##servername
:connect to X
insert into X.table values(#servername)
so i thought #servername gets the current servername and then it goes to line 3 and add it to new server(server X), but I was wrong and once it connects to server X it retrieves the data (#servername) from this server. meaning that it can't hold the data. So my question is how to hold the data from old server and not overwrite it, something like Static variable in java.
SQLCMD happens before processing the script, so you can't use it for your intended purpose.
Have you tried using a linked server and the EXEC AT command?
EXEC ('INSERT INTO MyTable VALUES (?)', #servername) AT [LinkedServer]
http://www.mssqltips.com/sqlservertip/1757/dynamic-sql-execution-on-remote-sql-server-using-exec-at/
https://msdn.microsoft.com/en-us/library/ms188332.aspx
If you have the server names before hand, you can use :setvar myvariable variablevalue to set a variable that you can access in your sqlcmd script via $(myvariable).
In this situation I would probably do a delimited string of server names to parse.
Take a look at the MSDN https://msdn.microsoft.com/en-us/library/ms188714.aspx , for more examples.
I have generated the stored procedures script for a database which is "Modern_Spanish_CI_AS". I run that script without problem in one server which has "SQL_Latin1_General_CP1_CI_AS" collation, but in another server which has "Modern_Spanish_BIN" collation, the script fails because some variables are declared #userLogin (or something else) and they are used #userlogin. CAPS vs no caps
There is no difference whether script is like:
EXEC dbo.sp_executesql #statement = N'my sp body'
or script is like:
CREATE PROCEDURE [dbo].MySpName
I have executed the following to ensure the database collation is the correct one:
SELECT DATABASEPROPERTYEX('MyDatabase','collation');/*returns "Modern_Spanish_CI_AS"*/
I'm not allowed to change server collation.
What could I do (other than change the case of the thousands of expressions) in order to succesfully run the script and ensure the sp's will work fine??? And, will there be an impact at runtime when a sp try to compare varchar values???
Thanks in advance
You must change the case of the thousands of expressions, learn your lesson, and in future always test your code in case sensitive collation servers.
I would like to execute dynamic SQL statements which are about 10,000 characters.
When I use sp_executesql as below:
DECLARE #stmt varchar(MAX)
SET #stmt = 'xxxxxxxx.................' which is about 10,000 characters
EXEC sp_executesql #stmt
I got the following error
The character string that starts with ' select t1.e_reference xxxxxxxxxxx' is too long. Maximum length is 8000.
As far as I know, we can use sp_executesql to execute very long statements, can't we?
I am using SQL Server 2008, Enterprise Edition, 64 bit.
How can I achieve this? Thanks.
Based on your responses in the post, you are using linked server.
The 8000 char limit is not posed by sp_executesql, but by OPENQUERY that you are probably using in your variable #stmt .
MSDN says this of OPENQUERY's arguments:
'query' Is the query string executed in the linked server. The maximum
length of the string is 8 KB.
http://msdn.microsoft.com/en-us/library/ms188427.aspx
To bypass this, you could probably use
execute (#query) at oracle_linked_server
MSDN says this which is a bit vague:
"The size of the string is limited only by available database server memory. On 64-bit servers, the size of the string is limited to 2 GB, the maximum size of nvarchar(max)."
On 64-bit servers the limit is 2GB. It is not clear what is the limit of 32-bit servers? Is it 4000, 8000, whatever memory is available, 2GB?
The #stmt parameter for sp_executesql has a data type of nvarchar(8000), so you have exceeded the limit.
Either refactor your SQL statements into smaller parts, or put the SQL into a stored procedure.
I recently encountered an issue while porting an app to SQL Server. It turned out that this issue was caused by a stored procedure parameter being declared too short for the data being passed to it: the parameter was declared as VARCHAR(100) but in one case was being passed more than 100 characters of data. What surprised me was that SQL Server didn't report any errors or warnings -- it just silently truncated the data to 100 characters.
The following SQLCMD session demonstrates this:
1> create procedure WhereHasMyDataGone (#data varchar(5)) as
2> begin
3> print 'Your data is ''' + #data + '''.';
4> end;
5> go
1> exec WhereHasMyDataGone '123456789';
2> go
Your data is '12345'.
Local variables also exhibit the same behaviour:
1> declare #s varchar(5) = '123456789';
2> print #s;
3> go
12345
Is there an option I can enable to have SQL Server report errors (or at least warnings) in such situations? Or should I just declare all local variables and stored procedure parameters as VARCHAR(MAX) or NVARCHAR(MAX)?
SQL Server has no such option. You will either have to manually check the length of strings in your stored procedure and somehow handle the longer strings or use the nvarchar(max) option. If disk space isn't an issue then the nvarchar(max) option is certainly the easiest and quickest solution.
You don't have to use nvarchar(max) just use nvarchar(length+1) [e.g. if your column length is 50 then you would set the parameter to be nvarchar(51)]. See the answer from DavidHyogo - SQL Server silently truncates varchar's in stored procedures.
I don't know of a way to make the server do it, but I've been using the SQL Server Projects feature of Visual Studio Team System Developer Edition. It includes code analysis which caught a truncation problem of mine: using an int parameter to insert into a smallint column.
Though awkward, you can, however, dynamically check for parameter length before a call, e.g.
CREATE FUNCTION MyFunction(#MyParameter varchar(10))
RETURNS int
AS
BEGIN
RETURN LEN(#MyParameter)
END
GO
DECLARE #MyValue varchar(15) = '123456789012345'
DECLARE #ParameterMaxLength int
SELECT #ParameterMaxLength = CHARACTER_MAXIMUM_LENGTH
FROM INFORMATION_SCHEMA.PARAMETERS
WHERE SPECIFIC_SCHEMA = 'dbo' AND
SPECIFIC_name = 'MyFunction' AND
PARAMETER_NAME = '#MyParameter'
IF #ParameterMaxLength <> -1 AND
LEN(#MyValue) > #ParameterMaxLength
PRINT 'It''s too looooooooooooooooooong'
I omitted the called function's database name in the query and in the reference to INFORMATION_SCHEMA.PARAMETERS to ensure that my sample would run without edits.
I don't necessarily advocate this, but I wanted to point out that the information may be available to detect imminent truncation dynamically, if in some critical situation this is needed.
You can use LEFT in SQL and specified the length that you want to insert.
for example.
CREATE TABLE Table1
(
test varchar(10)
)
insert into Table1 values (LEFT('abcdefghijklmnopqrstuvwxyz',10))
This will insert only
abcdefghij on table
How do I set the database name dynamically in a SQL Server stored procedure?
Sometimes, the use of SYNONYMs is a good strategy:
CREATE SYNONYM [schema.]name FOR [[[linkedserver.]database.]schema.]name
Then, refer to the object by its synonym in your stored procedure.
Altering where the synonym points IS a matter of dynamic SQL, but then your main stored procedures can be totally dynamic SQL-free. Create a table to manage all the objects you need to reference, and a stored procedure that switches all the desired synonyms to the right context.
This functionality is only available in SQL Server 2005 and up.
This method will NOT be suitable for frequent switching or for situations where different connections need to use different databases. I use it for a database that occasionally moves around between servers (it can run in the prod database or on the replication database and they have different names). After restoring the database to its new home, I run my switcheroo SP on it and everything is working in about 8 seconds.
Stored Procedures are database specific. If you want to access data from another database dynamically, you are going to have to create dynamic SQL and execute it.
Declare #strSQL VarChar (MAX)
Declare #DatabaseNameParameter VarChar (100) = 'MyOtherDB'
SET #strSQL = 'SELECT * FROM ' + #DatabaseNameParameter + '.Schema.TableName'
You can use if clauses to set the #DatabaseNameParameter to the DB of your liking.
Execute the statement to get your results.
This is not dynamic SQL and works for stored procs
Declare #ThreePartName varchar (1000)
Declare #DatabaseNameParameter varchar (100)
SET #DatabaseNameParameter = 'MyOtherDB'
SET #ThreePartName = #DatabaseNameParameter + '.Schema.MyOtherSP'
EXEC #ThreePartName #p1, #p2... --Look! No brackets