Error: assigning a variable output to other variable in snowflake procedure - variables

In one procedure I am calling other procedure where the result is assigned to the P_DATALAKEPATH variable and the ouput of internal procedure is READ|WRITE|UPDATE and I am trying to split the value and assign to the MY_VAR variable which is giving an getting error. Please help
var p_sqlText = `CALL LS_${P_ENV}.dbo.dbo(:1,:2)`
stmt = snowflake.createStatement({sqlText:p_sqlText,binds: ['1','2'] });
rs = stmt.execute();
rs.next();
var P_DATALAKEPATH = rs.getColumnValue(1);
set MY_VAR=SPLIT_PART(P_DATALAKEPATH,'|',1);

If the number of output variables is predictable, I suggest to not put multiple values in a single string and separate them by parsing the string in JS like you're trying to do.
Since your SQL generates a table, instead of putting everything in one column with a pipe separator, why not creating several columns in the output and get them back to your SP with rs.getColumnValue(1), rs.getColumnValue(2), rs.getColumnValue(3) etc?

You are mixing JavaScript and SQL in your code. This is SQL:
set MY_VAR=SPLIT_PART(P_DATALAKEPATH,'|',1);
You need to use JavaScript to split the value of P_DATALAKEPATH, and the get the first value:
var MY_VAR = P_DATALAKEPATH.split("|")[0];

Related

How do I add parameters to my queries when using clr/c++ for multiple variables

I want to be able to add parameters to my queries to make my statements less vunerable to sql injections
My code (Key parts are surrounded by ** as I cannot make code bold)
OleDbConnection^ existingSqlConnection = nullptr;
existingSqlConnection = gcnew OleDbConnection("Provider = Microsoft.ACE.OLEDB.12.0;" +
"Data Source =" + "myDatabaseV3.accdb");
**String^ sqlText = "SELECT * FROM #tableName WHERE #fieldName = #fieldEntityName";
OleDbCommand^ dbCommand = gcnew OleDbCommand(sqlText, existingSqlConnection);
OleDbParameterCollection^ paramCollection = dbCommand->Parameters;
dbCommand->Parameters->Add(gcnew OleDbParameter("#tableName", tableName->ToString()));
dbCommand->Parameters->AddWithValue("#fieldName", field);**
dbCommand->Parameters->AddWithValue("#fieldEntityName", fieldEntity);
**Console::WriteLine(dbCommand->CommandText);
Console::WriteLine(paramCollection->Count);**
existingSqlConnection->Open();
OleDbDataReader^ reader = dbCommand->ExecuteReader(System::Data::CommandBehavior::CloseConnection);
return reader;
The output for this is
SELECT * FROM #tableName WHERE #fieldName = #fieldEntityName
3
Which clearly shows that there are 3 parameters but they are not being added to my query which is the problem I want to be solved
This is not how parameters work. They are not replacement values for text templates. Parameters are a mechanism to pass in a value to the variable in the query, just like passing a parameter to a stored procedure will pass that value in to be used as a variable in the query.
Along these lines, parameters can only be used where variables can be used in queries. And, variables cannot be used for object names, which is why people resort to using SQL Injection when the table and/or column name(s) need to change. In your example code:
#tableName could never be a variable in a query, hence it cannot be a parameter
#fieldName could never be a variable in a query, hence it cannot be a parameter
#fieldEntityName if it is supposed to be a value and not a column name, can be a parameter, in which case it will remain as #fieldEntityName in the query, and it will have a value of fieldEntity.
Please see the second option of my answer on your related question for how to prevent SQL Injection (short answer: sanitize inputs).
Also, using AddWithValue() is a bad practice. Create the parameter with the intended max size, then give that a value, and finally add it to the parameters collection. You do not want it to auto-detect the max size for the parameter as it will use the first value it gets, and any subsequent value that is longer will be silently truncated.

Execute SQL Task -Full Result Set Datatype Mismatch Error

I am creating an SSIS package which has an execute SQL task and it passes result set variable to a for each loop container.
My Sql Query is:
Select distinct code from house where active=1 and campus='W'
I want the execute sql task to run this query and assign its results to a variable which is passed to a for each loop container which should loop through all the values in the result set.
But my execute sql task fails with error:
The type of the value (DBNull) being assigned to variable
"User::house" differs from the current variable type (String)
Now i have done my research and i have tried assigning the variable datatype Object but did not work. I tried using cast in my sql query and that also did not work.
Since my query returns multiple rows and one column, i am not sure how i can assign a datatype to the whole query?
Sample:
Code
AR
BN
CN
It sounds like you have a variety of issues in here.
Result Set
The first is in your Execute SQL Task and the need for agreement between the Result Set specification and the data type of the Variable(s) specified in the Result Set tab. If you specify Full Resultset, then the receiving object must be of type System::Object and you will only have 1 result set. The type of Connection Manager (ODBC/OLE/ADO) used will determine how you specify it but it's infinitely searchable on these fine forums.
The other two options are Single Row and XML. In 13 years of working with SSIS, I've never had cause to specify XML. That leaves us with Single Row. For a Single Row Result Set, you need to provide a variable for each column returned and it needs to be correctly typed.
To correct your issue, you need to declare a second variable. I usually call my rsObject (record set object) and then specify the data type as System.Object.
For Each Loop Container
Your For Each Loop Container will then be set with an Enumerator of "Foreach ADO Enumerator" and then the ADO object source variable will become "User::rsObject"
In the Variable Mappings, you'll specify your variable User::house to index 0.
Testing
Given a sample set of source source data, you can verify that you have your Execute SQL Task correctly assigning a result set to our object and the Foreach Loop Container is properly populating our variable.
SELECT DISTINCT
code
FROM
(
VALUES
('ABC', 1, 'w')
, ('BCD', 1, 'w')
, ('CDE', 0, 'w')
, ('DEF', 1, 'w')
, ('EFG', 1, 'x')
) house(code, active, campus)
WHERE
active = 1
AND campus = 'w';
If you change the value of campus from w to something that doesn't exist, like f then things will continue to work.
However, the error you're receiving can only be generated if the code is a NULL
Add one more entry to the VALUES collection like
, (NULL, 1, 'w')
and when the For Each Loop Container hits that value, you will encounter the error you indicate
The type of the value (DBNull) being assigned to variable "User::house" differs from the current variable type (String)
Now what?
SSIS variables cannot change their data type, unless they're of type Object (but that's not the solution here). The "problem" is that you cannot store a NULL value in an SSIS variable (unless it's of type object). Therefore you need to either exclude the rows that return a NULL (AND code IS NOT NULL) or you need to cast the NULL into sentinel/placeholder value as a substitute (SELECT DISTINCT ISNULL(code, '') AS code). If an empty string is a valid value, then you need to find something that isn't - "billinkcisthegreatestever10123432" is unlikely to exist in your set of codes but that might be a bit excessive.
Finally, think about renaming your SSIS variable from house to code. You might be able to keep things straight but some day you'll hand this code over to someone else for maintenance and you don't want to confuse them.
A picturesque answer https://stackoverflow.com/a/13976990/181965
the variable "User::house" is string , so , did you use it in result set?
you need declare son "object" var for result set
result set
then declare a string variable for every single Code from your result
For Each Loop Container
good luck

Update command in sql having issue

I have below details in the table
GEMS#TEST1>select BUILTIN_ARGUMENTS from FND_FORM_CUSTOM_ACTIONS WHERE (RULE_ID = 2243);
BUILTIN_ARGUMENTS
--------------------------------------------------------------------------------
='http://prod.client.com:3001/ords/f?p=1:2:::NO::P_ORDER_HEADER_ID,P_SESSION
_ID:'||${item.ORDER.HEADER_ID.VALUE}||','||${ps.db_session_id.value}
For a need ,I have to update this "prod.client.com:3001" as
"test1-scan.client.com"
When I am executing below getting error
GEMS#TEST1>update FND_FORM_CUSTOM_ACTIONS set = '='http://test1-scan.client.com/ords/f?p=1:2:::NO::P_ORDER_HEADER_ID,P_SESSION
_ID:'||${item.ORDER.HEADER_ID.VALUE}||','||${ps.db_session_id.value}' WHERE (RULE_ID = 2243);
SP2-0552: Bind variable "NO" not declared.
GEMS#TEST1>
I know I might have to use escape character or declare the variable but not getting clue as I am not very good in coding .
Using REPLACE in this case is better.
UPDATE fnd_form_custom_actions
SET builtin_arguments = REPLACE (builtin_arguments, 'prod.client.com:3001',
'test1-scan.client.com')
WHERE rule_id = 2243 ;
You have obvious typos in your statement:
set = '='http://test1-scan.client.com/ords/f?p=1:2:::NO [.......]
set what = .....?
Then: what is with the second equal sign, in single quotes? (OR... I see - did you mean single quotes within the assigned string? You must enter TWO single quotes to represent one single quote in a string!)
Then: since the second equal sign consumes the single quotes, what follows AFTER it is not quoted. So :NO is seen as a bind variable. Correct the syntax and Oracle won't ask you about any bind variables.
With that fixed, look at Kaushik's answer for a better approach altogether.

SSIS: How do I pass string parameter in an update statement in Execute SQL Task?

I have one execute SQL Task in SSIS 2012 which has update statement. I want to pass a string variable in the where clause of this update statement. The update section is as below:
where coalesce(s1.iteration, '') not like '%?%' and s2.Iteration = '?'
Here, ? needs to be replaced with a string variable, which in this case would be 08152017. I have added the variable to the Parameter Mapping. Screenshot is attached.
The task executes successfully but does not updates the value in the intended column. It seems the query is not passing the value.What am I doing wrong? How do I check that the SQL inside the Execute SQL Task is actually getting the value from the variable?
First of all, when you set your variable in parameter mapping, make sure the datatype is NVARCHAR and not LONG.
Second you need to write your statement like this:
where coalesce(s1.iteration, '') not like '%?%' and s2.Iteration = ?
You dont need '' because your variable is already set as a string.
Try to hardcode your value in your variable to see if it passes. Otherwise, set a breakpoint on pre-execute to see wheter your variable has a value.
If your variable has a value and your SQL is not working, maybe you should look into your SQL. Maybe try it directly in SSMS to see if it actually runs or does anything.
In scenario ? is Integer type variable, then please use below format:
SELECT ? +' Hello World!'
The above does not require the use of an additional string variable.
Create a user variable with % on it, for example, variable name is Like_Var with data type String
"%" + #Orig_Var + "%"
Let's say, Orig_Var has a value of 08152017, therefore Like_Var will have %08152017%
Then use Like_Var on your parameter in Execute SQL Task as parameter 0, data type VARCHAR in Parameter Mapping
WHERE COALESCE(s1.iteration, '') NOT LIKE ?
AND s2.Iteration = ?

one variable for all the sql output

myRs=myStmt.executeQuery("select i_col,col_name from tab_col")
i=0
while (myRs.next()):
list= myRs.getString("I_COL")+','+myRs.getString("COL_NAME")
i have a jython code to run a sql statement i want to store all the row of the sql into a single variable. I used to list to store the value but its always storing only the single line , so is there is way to append all the rows and keep adding to single variable.
Thanks so much for your help.
With that code you overwrite the "list" variable in every iteration of the while loop (= is an assignment), try something like this (I used rs rather than list to avoid a name clash with the builtin function list()):
myRs=myStmt.executeQuery("select i_col,col_name from tab_col")
rs=[]
i=0
while (myRs.next()):
rs.append(myRs.getString("I_COL")+','+myRs.getString("COL_NAME"))