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.
Related
I am trying to create the script in netezza like what we do in SQL server with variable declaration but I am not able to do it.
Need to create a temp table and then need to pass the parameter to it through a variable.
DECLARE var1 varchar(10);
through error message every time
How to drop a temp table. and how the temp table data is stored and cleared in the memory?
Netezza has its own language for stored procedures - same concept as SQLserver but closer to oracle syntax.
It is however not possible to use the 'variables' construct outside such a stored procedure, which leaves you with a couple of options in your case:
1. do a 'create or replace procedure' with your script embedded, and the execute the sp
2. store intermediate results in temporary tables, and do the 'if-then-else' logic in another scripting language (perl powershell or the like)
We went for option 1 in most cases when moving from SQLserver to Netezza about a year ago...
I've inherited a complicated application that uses a lot of dynamic SQL. Many of the stored procedures construct and execute significantly different SQL statements depending on input parameters. Is there a way that I can see the executed SQL, without using SQL profiler - ideally from within SQL Server Manager Studio?
I did something more-or-less along the same lines by creating a table called 'WhatHappened' with an AutoInc BigInt as a primary key, and a big varchar(8000) field to hold the dynamically created SQL commands, and then simply wrote the dynamically created SQL into the table, and looked at it with Enterprise Manager later. I don't know if it's a great solution, but it was quick and simple and worked.
You can use PRINT statement
for exp.
IF ##OPTIONS & 512 <> 0
PRINT N'This user has SET NOCOUNT turned ON.';
ELSE
PRINT N'This user has SET NOCOUNT turned OFF.';
GO
use like
PRINT #YourDynamicSQLStatement
ref. https://msdn.microsoft.com/en-IN/library/ms176047.aspx
I would like to know whether my stored procedure will get impacted without specifying Go
Here is the code flow:
Create or replace store_proc1
As
Begin
While loop
{SQL statements repeating itself until source table record count is 0}
End
"Go"
Here I have missed Go at the end of my stored procedure.. Will it impact the performance?
GO is not a SQL statement - it's a delimiter used only in SQL Server Management Studio.
So no, omitting GO will NOT in any way affect your stored procedure's ability to run, nor it performance.
I have a case sensitive SERVER (SQL_Latin1_General_CP1_CS_AS) but the Database is Case insensitive (SQL_Latin1_General_CP1_CI_AS).
If I try to create the following stored procedure on the database, I get the error "Must declare the scalar variable "#test"."
CREATE PROCEDURE [dbo].[sp_Test] (#TEST int) as
begin
SELECT #test
end
GO
But as I stated the database itself is not case sensitive. Im assuming this is documented somewhere that stored procedures follow the sensitivity of the server but I cannot find a reference anywhere. Can anyone point me to where I would find some docs about this? (Yes I tried google, but im not finding anything)
You are right. Database collation does not control variables name case sensitivity - server collation does.
Any other object name (e.g. table, view, column) follows database collation rules. In your situation, that means case insensitive, since your database is CI (case insensitive).
From the SQL Server Books Online:
COLLATE (Transact-SQL)
The collation of an identifier depends on the level at which it is defined.
Identifiers of instance-level objects, such as logins and database names, are assigned the default collation of the instance.
Identifiers of objects within a database, such as tables, views, and column names, are assigned the default collation of the database.
For example, two tables with names different only in case may be created in a database with case-sensitive collation, but may not be created in a database with case-insensitive collation. For more information, see Database Identifiers.
The identifiers for variables, GOTO labels, temporary stored procedures, and temporary tables are in the default collation of the server instance.
Variables, GOTO labels, temporary stored procedures, and temporary tables can be created when the connection context is associated with one database, and then referenced when the context has been switched to another database.
You can check your server collation using:
SELECT SERVERPROPERTY('collation');
SQL_Latin1_General_CP1_CI_AS
(1 row(s) affected)
See also
MSDN forums: Why are my SP's throwing a case error when pushing to a db using BIN collation?
Case sensitive variables in SQL Server
Case sensitive variable names in SQL Server?
Where I'm at we have a software package running on a mainframe system. The mainframe makes a nightly dump into sql server, such that each of our clients has it's own database in the server. There are a few other databases in the server instance as well, plus some older client dbs with no data.
We often need to run reports or check data across all clients. I would like to be able to run queries using sp_msforeachdb or something similar, but I'm not sure how I can go about filtering unwanted dbs from the list. Any thoughts on how this could work?
We're still on SQL Server 2000, but should be moving to 2005 in a few months.
Update:
I think I did a poor job asking this question, so I'm gonna clarify my goals and then post the solution I ended up using.
What I want to accomplish here is to make it easy for programmers working on queries for use in their programs to write the query using one client database, and then pretty much instantly run (test) code designed and built on one client's db on all 50 or so client dbs, with little to no modification.
With that in mind, here's my code as it currently sits in Management Studio (partially obfuscated):
use [master]
declare #sql varchar(3900)
set #sql = 'complicated sql command added here'
-----------------------------------
declare #cmd1 varchar(100)
declare #cmd2 varchar(4000)
declare #cmd3 varchar(100)
set #cmd1 = 'if ''?'' like ''commonprefix_%'' raiserror (''Starting ?'', 0, 1) with nowait'
set #cmd3 = 'if ''?'' like ''commonprefix_%'' print ''Finished ?'''
set #cmd2 =
replace('if ''?'' like ''commonprefix_%''
begin
use [?]
{0}
end', '{0}', #sql)
exec sp_msforeachdb #command1 = #cmd1, #command2 = #cmd2, #command3 = #cmd3
The nice thing about this is all you have to do is set the #sql variable to your query text. Very easy to turn into a stored procedure. It's dynamic sql, but again: it's only used for development (famous last words ;) ). The downside is that you still need to escape single quotes used in the query and much of the time you'll end up putting an extra ''?'' As ClientDB column in the select list, but otherwise it works well enough.
Unless I get another really good idea today I want to turn this into a stored procedure and also put together a version as a table-valued function using a temp table to put all the results in one resultset (for select queries only).
Just wrap the statement you want to execute in an IF NOT IN:
EXEC sp_msforeachdb "
IF '?' NOT IN ('DBs','to','exclude') BEGIN
EXEC sp_whatever_you_want_to
END
"
Each of our database servers contains a "DBA" database that contains tables full of meta-data like this.
A "databases" table would keep a list of all databases on the server, and you could put flag columns to indicate database status (live, archive, system, etc).
Then the first thing your SCRIPT does is to go to your DBA database to get the list of all databases it should be running against.
We even have a nightly maintenance script that makes sure all databases physically on the server are also entered into our "DBA.databases" table, and alerts us if they are not. (Because adding a row to this table should be a manual process)
How about taking the definition of sp_msforeachdb, and tweaking it to fit your purpose? To get the definition you can run this (hit ctrl-T first to put the results pane into Text mode):
sp_helptext sp_msforeachdb
Obviously you would want to create your own version of this sproc rather than overwriting the original ;o)
Doing this type of thing is pretty simple in 2005 SSIS packages. Perhaps you could get an instance set up on a server somewhere.
We have multiple servers set up, so we have a table that denotes what servers will be surveyed. We then pull back, among other things, a list of all databases. This is used for backup scripts.
You could maintain this list of databases and add a few fields for your own purposes. You could have another package or step, depending on how you decide which databases to report on and if it could be done programmatically.
You can get code here for free: http://www.sqlmag.com/Articles/ArticleID/97840/97840.html?Ad=1
We based our system on this code.