When I run this query in SQLCMD mode in SSMS 2017 and SQL Server DB. It works fine.
--SQLCMD mode
--DECLARE Global variables
:SETVAR daysBack -1
SELECT $(daysBack)
Result: -1
If I run only 1 line
SELECT $(daysBack)
in the same window on the same connection, or in another tab. I am getting error
fatal scripting error occurred.
Variable daysBack is not defined.
Why I am getting error?
and how can I make my varibale Global, for example like
SELECT '$(COMPUTERNAME)'
I don't think you can. SQLCMD variables are a client tool trick, they don't really exist as a SQL Server concept.
The connection and server are not aware of their existence and the system doesn't persist knowledge of variables used in previous batches when you submit a new batch.
From sqlcmd - Use with Scripting Variables:
If more than one type of variable has the same name, the variable with the highest precedence is used.
System level environmental variables
User level environmental variables
Command shell (SET X=Y) set at command prompt before starting sqlcmd
sqlcmd-v X=Y
:Setvar X Y
Of these, the first three are effectively taken from when a particular process was launched, unless that process has specific tooling to allow environmental variable to be edited. Neither SSMS nor SQLCMD has such functionality so you cannot create a variable in these categories once the tool is already running.
The fourth is SQLCMD specific and has no equivalent in SSMS. Only the last one (using :setvar) remains, and this does not create a "global" variable (which are in fact just the environmental variables and the SQLCMD built-in variables).
Related
I am designing an incremental load for my ETL solution in SSIS. For that, I have an Execute SQL task that gets the maximum load time from the data warehouse and then stores it in a package variable, which is already set to evaluate as expression.
Then I have set the ODBC source's sql command property to an expression that has my query and the variable. However, I have looked into the variable during debug and when I run the package it seems that this variable doesn't get used in the sql command, instead it remains null.
I have already tried setting the variable property 'EvaluateAsExpression' to True, I have tried storing the query in a different variable and then setting that as the sql command for my ODBC source.
Very often extremely trival edits cause my T-SQL scripts to fail when rerun from within a MS SQL Server 2012 edit window (e.g. "SqlQuery1.txt"). Frustratingly, there's no pattern to what (edits) cause this problem. Coping with this has forced me to jump through some wierd hoops.
An example: I changed exactly 1 character in a working query (from "Set #THisColumn = 1" to "Set #ThisColumn = 1"; the "H" was changed to "h'" to match the variable declaration). When the script was rerun MS SQL Server 2012 gave me this error:
Msg 213, Level 16, State 1, Line 54
Column name or number of supplied values does not match table definition.
My research shows this message gets thrown when there is a problem with a TABLE which should be impossible in the above case. The error is unimportant, my problem is much more general - having to use the following unsatisfactory "workaround":*
Copy the (edited) script into a new edit pane ("SQLQuery2.txt"). It works - until the next time it's edited. Which then forces me to use another edit pane ("SQLQuery3.txt"). Repeat ad nausum.
Having to do this supports the theory that the problem is somehow related to how the edit pane works - NOT the script. (Hence the title of this question)
Using this "workaround" destroys my train of thought while the resulting large number of open "scratchpad" windows causes me to lose track of what I was doing ("... lets see now, is it version 13, 17, 26 or 28 that is the last "known good" version?...).
My suspicion is that SQL considers every subsequent rerun as being a part (a continuation) of the FIRST invocation of that script. So it tries to be "helpful" (not!) by "optimizing" the query.
In a development environment this "assistance" is very premature - and exactly what I do NOT want to have happen. (First make it work...then optimize it.) How do I supress this undesirable behavoir?
From my research I know that my scripts must have lines like this one before creating a temporary table:
IF OBJECT_ID( 'tempdb..#XYZ) IS NOT NULL DROP TABLE #XYZ
and for a temporary procedure:
IF OBJECT_ID( 'tempdb..#ABCD) IS NOT NULL DROP PROCEDURE #ABCD
GO -- Required before defining any procedure
CREATE PROCEDURE #ABCD
The need to do this implies that my supposition may be correct (why else would you need to do it?).
What else has to be done so that every time I press the "execute" button I get a "clean restart" of SQL?
Other factors to keep in mind:
The script, invoked from Python 3.x, is periodically (and
frequently) run as batch/cron job (i.e. an automatically scheduled
task). This means that any form of manual intervention (e.g. using
tools like MS 2012 Management Studio etc.) is not an option.
Stored procedures aren't allowed, instead the python application reads a file of SQL commands that get passed to SQL for execution
(in effect emulating a user who types in those commands at a SQL
console).
Finally the script must also work for users that have the minimum
possible (e.g "guest") privileges
.
My SSDT database publish is failing because it is erroneously thinking an embedded string is referring to a SQLCMD variable:
EXEC xp_cmdshell 'powershell.exe $(Get-Date).IsDaylightSavingTime()'
I can manually run this statement (in SSMS) and get the desired result (which is regrettably "true") but the publish chokes trying to parse the statement:
SQL Execution error: A fatal error occurred. The variable Get-Date could not be found.
SQL Execution error: A fatal error occurred. Incorrect syntax was encountered while EXEC xp_cmdshell 'powershell.exe $(Get-Date).IsDaylightSavingTime()' was being parsed.
How do I get this statement to not fail the publish without obfuscating it or adding it to the SQLCMD variable list in the database project?
(Or perhaps there is an easier way to check if the server's time zone observes godforsaken DST? The time zone identifiers in the USA say "Standard" regardless if actually prevailing on our developer machines. And changing all references from GETDATE() to GETUTCDATE() is not feasible.)
Haven't seen this before but then again I've never tried to call powershell from t-sql :).
The simplest would be to split the string passed to xp_cmdshell using something like this:
https://social.msdn.microsoft.com/Forums/sqlserver/en-US/4a07d229-7972-41d1-bd90-ffa979bc7069/how-to-escape-string-that-sqlcmd-thinks-is-a-variable-but-isnt?forum=transactsql
' + CHAR(36) + '
Re a simpler solution without powershell, Not sure if I could envisage a more painful thing to have to do on t-sql, sorry :)
I'm create a SQL Server Report using Business Intelligence tool (visual studio shell 2005) for SQL Server 2008.
I'm calling a stored procedure with 2 parameters. I've tried - Report-> Report Parameter, Added two parameters name them Days and Count.
In the Data panel "command type:text"
exec dbo.DataReport #Days, #Count
error: Must delcare the scalar variable "#Days"
Does anyone know how do get this too work.
Try changing the command type to Stored Procedure, i'm sure its worked for me in the past
If changing the command type to Stored Procedure like was suggested didn't work, try opening the Dataset dialog box and going to "Parameters" tab. Make sure that both parameters ("#Days" and "#Count") are in the list and that each one has a value.
I would like to run some ad hoc select statements in the IBM System I Navigator tool for DB2 using a variable that I declare.
For example, in the SQL Server world I would easily do this in the SQL Server Management Studio query window like so:
DECLARE #VariableName varchar(50);
SET #VariableName = 'blah blah';
select * from TableName where Column = #VariableName;
How can I do something similar in the IBM System I Navigator tool?
I ran across this post while searching for the same question. My coworker provided the answer. It is indeed possible to declare variables in an ad hoc SQL statement in Navigator. This is how it is done:
CREATE OR REPLACE VARIABLE variableName VARCHAR(50);
SET variableName = 'blah';
SELECT * FROM table WHERE column = variableName;
DROP VARIABLE variableName;
If you don't drop the variable name it will hang around until who knows when...
At the moment, we're working on the same issue at work. Unfortunaly, we concluded that this is not possible. I agree, it would be great but it just doesn't work that way. iNavigator doesn't support SET or Define. You can do that in embedded SQL but this is not embedded SQL. Even if you create a separate document (xxx.sql), then need to open this document to run the script what makes it an interactive script (that is, DECLARE SECTION is not allowed).
As an alternative, in the SQL screen/script you can use CL:. Anything after this prefix is executed as CL command. You may manipulate your tables (e.g. RNMF) this way.
As a second alternative, the iSeries does support Rexx scripts (default installed with the os). Rexx is good dynamic script language and it does support embedded SQL. I've done that a lot of times and it works great. I even created scripts for our production environment.
Just create one 'default' script with an example PREPARE and CURSOR statement and copy at will. With that script you can play around. See the Rexx manual for the correct syntax of exec-sql. Also, you do have STDIN and STDOUT but you can use 'OVRDBF' to point to a database table (physical file). Just let me know if you need an example Rexx script.
Notice that the manual "SQL embedded programming" does have Rexx examples.
Here are a couple of other alternatives.
Data Transfer Tool - You can run the iSeries Data Transfer Tool from the command line (RTOPCB). First, run the GUI version and create a definition file. If you edit this file with a text editor, you will see that this is just an old-fashioned INI file and you can easily find the line with the query in it. From there, you could write a batch file or otherwise pre-process the text file to allow you to manipulate the query before submitting it to the query tool.
QSHELL - If you can log on to the iSeries interactively, then you may find the QSHELL environment more familiar than CL or REXX (although REXX is kind of fun). QSHELL is a full POSIX environment running on the iSeries. Use the command STRQSH to start QSHELL. You can have ksh or csh as a shell. Inside QSHELL, there is a command called "db2" that submits queries. So, you should be able to do something like this inside QSHELL:
system> VariableName = 'blah blah'
system> db2 "select * from TableName where Column = \'$VariableName\'"
You may have to fiddle with the quotes to get ksh to pass them correctly.
Also, inside QSHELL, you should have a full Perl installation that will allow you to use DBI to get data.
Some other ways to interact with data on the iSeries: query from the client with Python via ODBC; query from the client with Jython via JDBC; install Jython directly on the iSeries and then query via JDBC.