Difficulty using CAST/CONVERT with SQLCMD in order to assign stored procedure variables - sql-server-2008

I am attempting to make a stored procedure work by triggering the SP through a batch file using SQLCMD, with user-defined variables. I can already confirm my stored procedure works, because I tested it this way using hard-coded variables.
For reference, this is the batch file code:
SET /P Param1 = Enter job number here:
SET /P Param2 = Enter number for current status here:
sqlcmd -S DevTest -d test_database -Q "EXEC dbo.JStatUpd #jobNum = Param1, #stat = Param2"
PAUSE
(EDIT: I have left the sqlcmd line as-is for ease of reference.)
My difficulty lies in working with user-defined variables. Specifically, I'm having an issue converting the user-defined variables--both of my variables should be integers.
I recognize that all of the SET variables automatically come in as nvarchar, but I haven't been able to find a way to convert them to int; I've gotten errors for each attempt I've made at using CAST or CONVERT.
My question is: Is it possible to to convert variables using CAST or CONVERT inside the SQLCMD in-line query? Or am I going about this the wrong way when I ought to be using a different method?

#Nishad had the right idea, but it turns out that something else needed fixing as well. For the sake of being thorough, here's the final batch file code I wound up using:
SET /P Param1 = Enter job number here:
SET /P Param2 = Enter current status here:
sqlcmd -S DevTest -d test_database -Q "EXEC dbo.JStatUpd #jobNum=N'%Param1%', #stat=%Param2%"
PAUSE
It was only with this specific formatting that I could actually get my user-entered values to work properly; #echo showed me that I was getting blanks no matter what I entered, so I started playing with the query parameter formats and found that this worked.

Related

TCL - Reading console output (not keystrokes)

So I am very new to TCL commands and I have to write a simple query which would read the hash value generated by a command.
TCL query is part of a bigger script where we need to generate a hash value using tcl command.
Below is the whole scenario:
Basically, need to execute a command to generate HASH value.
For ex:
request password-hash -password <password_value>
Once above command is executed, the shell will provide a hash value. This hash value then should be provided to another command.
For ex:
set password-hash <above generated value here>
After a lot of searching I think exec command will give the hash as output, I was then planning to store it in some variable using set command, something like below:
set hash_value [exec request password-hash -password <password_value>]
& then
set password-hash $hash_value
however, I am facing error that tcl evaluation failing.
The script 'set hash_value [exec request password-hash -password <password_value>];' evaluation failed. Error: System.ComponentModel.Win32Exception (0x80004005): The system cannot find the file specified
Is exec command correct way of doing the what I actually wanted to do?
Since evaluation is failing, I think some syntax issue is there maybe?
Any better way to read console output and provide it as input to another command?
Thanks!!

skip-column-names not working for a call inside script

I have a stored procedure myProc defined within a file stored_proc.sql that has select statements to report on various things.
If call myProc within stored_proc.sql, skip-column-names works.
I'd like to call myProc within another file overall.sql, but, if I do SOURCE stored_proc.sql and CALL myProc() within overall.sql, skip-column-names stops working.
I'm executing overall.sql like this:
mysql <connection properties> --skip-column-names -e "SOURCE overall.sql"
Looks like --skip-column-names may not work with the -e option, but -skip-column-names does work, if the *.sql file's pipe through either through | or < (e.g. cat overall.sql | mysql <...> --skip-column-names). I was hoping to use -e to be able to set a session variable, but doing a sed replacement (like in this SO post) also works.

Escaping ampersands in JSON for Oracle

We are sending JSON to an oracle function and sometimes it contains ampersands. I'd like to know if there is any other way to prevent the "variable substitution" problem because of the ampersand without having to modify the string to
'{"this is the JSON &'||' it contains an ampersand"}'
I've tried these and they DO NOT WORK.
'{"this is the JSON && it contains an ampersand"}'
'{"this is the JSON /& it contains an ampersand"}'
'{"this is the JSON \\& it contains an ampersand"}'
Edit:
This is how we manually import in Toad:
declare
vOut varchar2(400);
begin
vOut:=CartJSON.RequestEntry('JSON HERE'); -- function to parse JSON
dbms_output.put_line('Here:'||vOut);
end;
Update
OP is using TOAD and not SQL*Plus.
TOAD
In TOAD, there are three ways to execute statements without substituting a value for the ampersand(&):
Menu Level
View -> TOAD Options: go to the "execute/compile" node/item and
uncheck the "Prompt for substitution variables" option.
Editor Level
Right click in the editor and uncheck the "Prompt for substitution
variables" option.
Execute as script using set define off
Most of the GUI based tools like SQL Developer, TOAD etc. now support a lot of SQL*Plus commands and executing as script seems quite similar to that in SQL*Plus. However, it is very much possible that older versions of the GUI tool might not support the SQL*Plus commands.
SQL*Plus
The use of ampersand as a substitution variable is an Oracle SQL*Plus client feature.
In SQL*Plus you could do
SET DEFINE OFF
For example,
SQL> SET DEFINE OFF
SQL> SELECT '{"this is the JSON && it contains an ampersand"}' str FROM dual;
STR
------------------------------------------------
{"this is the JSON && it contains an ampersand"}
Or,
SET SCAN OFF
For example,
SQL> SET SCAN OFF
SQL> SELECT '{"this is the JSON && it contains an ampersand"}' str FROM dual;
STR
------------------------------------------------
{"this is the JSON && it contains an ampersand"}
SQL>
Or,
Alternatively, you could use CHR(38) for the ampersand.
For example,
SQL> SELECT '{"this is the JSON '|| chr(38)||chr(38) ||' it contains an ampersand"}' str FROM dual;
STR
------------------------------------------------
{"this is the JSON && it contains an ampersand"}
SQL>
Ok, so now we know you're using Toad, the issue is that you're trying to run the set define off as if it's a sql statement (Execute statement at caret / F9) and not as a SQLPlus statement (ie. as part of a script - Execute as script / F5). You have two options:
1: Run both statements as a script (F5):
set define off;
declare
vOut varchar2(400);
begin
vOut:=CartJSON.RequestEntry('JSON HERE'); -- function to parse JSON
dbms_output.put_line('Here:'||vOut);
end;
/
Click with the right mouse button on the editor window and turn off the Substition Variable Prompting, and then run your anonymous block as a single statement (F9).

Unix: Passing Param to MYSQL files from BASH Shell Script

I want to pass SOME VARIABLES to mysql file from bash shell script.
Here is my shell script.
#!/bin/bash
echo $0 Started at $(date)
mysql -uroot -p123xyzblabla MyMYSQLDBName<mysqlfile.sql PARAM_TABLE_NAME
Please note that it is MYSQL and not SQLPLUS
My MYSQL.sql , I want to read and use passed parameter/argument (PARAM_TABLE_NAME)
select count(*) from PARAM_TABLE_NAME
Question 1: What is the correct syntax to pass variable(PARAM_TABLE_NAME) to sql file (mysqlfile.sql)?
Question 2: How can I print variable(PARAM_TABLE_NAME) in sql file (mysqlfile.sql)?
Basically, I want to make generic SQL script which can load or select data from tables based on received inputs.
Thanks
There is no such thing as passing a parameter to a SQL file. A SQL file is no more than a text file that contains a list of SQL statements. These statements are interpreted by the mysql client program exactly as if you typed them on your keyboard.
The mysql client does not provide the feature you are looking for.
But I can think of a few tricks to achieve a similar effet:
create/populate a configuration table prior to reading your SQL file. Then write your SQL file so that it takes this table contents into account:
bash> mysql -e "INSERT INTO config_table VALUES(1, 2, 3)"
bash> mysql < script.sql
prepend your SQL file with some variables declarations. Then use these variables in the rest of your script:
bash> (echo "SET #var=123;" ; cat script.sql) |mysql
[example script.sql]
SELECT * FROM mytable WHERE id = #var;
write your SQL file with some placeholders that your replace on the fly, e.g with sed:
bash> sed "s/__VAR_A__/mytable/g" script.sql |mysql
[example script.sql]
SELECT * FROM __VAR_A__ WHERE id = 123;
All the above is quite dirty. A much cleaner solution would involve stored procedures or functions. Then you would just pass your parameters as procedure parameters:
bash> PARAM1='foo'; PARAM2='bar'
bash> mysql -e "CALL MyProc($PARAM1);"
bash> mysql -e "SELECT MyFunc($PARAM2);"
note: it is not possible to parametrize a table name in SQL, so you will need to resort to dynamic SQL like this in all cases (except for the sed-based hack, which I do not recommend)
This is an old thread but I think may still be useful to some people. Something like this should work:
mysql -uroot -p123xyzblabla MyMYSQLDBName -e "set #testVar='customer_name'; source mysqlfile.sql;"
Now #testVar (customer_name) is available for you to use in mysqlfile.sql file.
HTH
The way to pass parameters has already been answered in this or other threads. However, specific to the sample in you question, I'd like to add that you can't use the variables declaration method as a placeholder for a table name, as the documentation says:
User variables are intended to provide data values. They cannot be used directly in an SQL statement as an identifier or as part of an identifier, such as in contexts where a table or database name is expected
If you want to use a table name parameter, you can still use the sed or the stored procedures or functions as answered by #RandomSeed
In addition to that, another way is using PREPARE and EXECUTE in your script. The following example allows you to create a database/schema (in case you wanted to use stored procedures you need to have them already stored in a database), like this:
[myscript.sql]
set #s=CONCAT("CREATE DATABASE ", #dbname);
PREPARE stmt FROM #s;
EXECUTE stmt;
Then use any of the proposed syntax in the other questions to set the #dbname variable:
mysql -uroot -p123xyzblabla MyMYSQLDBName -e "set #dbname='mydatabase'; source myscript.sql;"

setting a c-shell variable to a SELECT statement

i have written a c-shell script to connect to a database. This already works just fine and i now want to invoke an sql script to read and print ALL the values in a cetrain table. As of now this is how my script looks
#!/bin/csh
set MYSQL=${MYSQL_HOME}/mysql
${MYSQL} ${CLEDBUSER}
where CLEDBUSER is set as an environment variable like so - CLEADBUSER=-uusername -ppassword -Ddatabasename
i am able to run the script and connect to the database. When i runt he script it gives me the msql pront awaiting the next command. So i added to the script a variable that contains the (SELECT) statement to query the database. Now my script looks like this
#!/bin/csh
set MYSQL=${MYSQL_HOME}/mysql
set SELECTER="SELECT * FROM TB_EARTH_UI;"
${MYSQL} ${CLEDBUSER} ${SELECTER}
the problem is it doesnt return me all the rows and columsn but it returns me a listing of avaiable commands in mysql promt and default options and also vairables and boolean options. Why is my SELECT statement not getting read?
MySQL client (mysql) expects SQL instructions on its standard input (e.g. your keyboard, when invoking from the shell).
You could do: [edit: please ignore, this one is off-topic]
${MYSQL} ${CLEDBUSER} < text_file_of_sql_statements.sql
or
${MYSQL} ${CLEDBUSER} << EOF
${SELECTER}
# you can add other litteral SQL statements here, or more variables containing SQL statements
EOF
or
${MYSQL} ${CLEDBUSER} --execute="${SELECTER}"
[edit]
I totally misunderstood the OP's question. I didn't get it that he was trying to execute SQL statements from a variable. I have edited the above options (thank you outis). Here is another variation:
echo ${SELECTER} | ${MYSQL} ${CLEDBUSER}
Also, the --skip-column-names option could make it easier for you to parse the output.