trying to concatenate session variables in Java script for snowflake - snowflake-cloud-data-platform

I have two databases $a_database and $b_database. I am trying to see how to concatenate these two. I have used "Binds" and also "if else". Any other method that I can concatenate?

You do not need to use JavaScript to concatenate two Snowflake session variables. You can do it there, but it would be more complex than doing it just issuing SQL statements.
set a_database = 'Hello';
set b_database = ', world';
set c_concatenated = (select $a_database || $b_database);
select $c_concatenated;
The key thing is when you're assigning something other than a simple literal value, you have to wrap a select statement in parenthesis.

Related

SPLIT_PART function used in a select statement in Snowflake Stored procedure returns null value

SPLIT_PART function used in a select statement in Snowflake Stored procedure returns null value.
var stmt5 = snowflake.CreateStatement({sqltext:`Select SPLIT_PART(SPLIT_PART(:1,''/'',2),''.gz'',1)`,binds:[stagename]});
var queryText=stmt5.getSqlText();
var x=stmt5.execute();
x.next();
stagename is retrieved from the List #my_stage command result and the result of the Split Part is used in the Copy Command for inserting records into a snowflake table.
If somebody responds will share the code thru an email to help me fix the issue. Thanks in advance.
You're using JavaScript with backticks, so there's no need to escape the single quotes. By doing so, it actually looks like an empty string. This is how it would look in your SQL history tab:
Select SPLIT_PART(SPLIT_PART(:1,''/'',2),''.gz'',1)
If you put a file name in and try that:
Select SPLIT_PART(SPLIT_PART('mypath/myfile.gz',''/'',2),''.gz'',1)
This doesn't actually return a null value. It's a syntax error, so maybe this execute call is in a try/catch block. That would return a null value when you try to use .next(),
Try it with the quotes single:
var stmt5 = snowflake.CreateStatement({sqltext:`Select SPLIT_PART(SPLIT_PART(:1,'/',2),'.gz',1)`,binds:[stagename]});

SQL Server - add to this query to first check for existence of a string

I have an nvarchar field in my database called CatCustom which contains comma-separated 5-character codes. It can contain as little as one code, or as many as 20 codes, separated by commas.
Right now, I use this query to add a new 5-character code to the field in given records (in this case the new code is LRR01):
UPDATE dbo.Sources
SET CatCustom = CONCAT_WS(', ', RTRIM(CatCustom), 'LRR01')
WHERE SourceID IN (1,2,3,4,5,8,9,44,63,45,101,102,222,344)
I need to add to this though: I need the record to be updated only if that 5-character code doesn't already exist somewhere in the CatCustom field, to ensure that code is not in there more than once.
How would I accomplish this?
EDIT: I really don't understand how this can be considered a duplicate of the suggested thread. This is a VERY specific case and has nothing to do with creating stored procedures and or variables. The alleged duplicated thread does not really help me - sorry.
Use STRING_SPLIT function to split the comma separated list and then add Not Exist condition in the WHERE clause like below
UPDATE dbo.Sources
SET CatCustom = CONCAT_WS(', ', RTRIM(CatCustom), 'LRR01')
WHERE SourceID IN (1,2,3,4,5,8,9,44,63,45,101,102,222,344)
AND NOT EXISTS (SELECT 1 FROM STRING_SPLIT(CatCustom, ',') where value = 'LRR01')
UPDATE dbo.Sources
SET
CatCustom = CONCAT_WS(', ', RTRIM(CatCustom), 'LRR01')
WHERE
SourceID IN (1,2,3,4,5,8,9,44,63,45,101,102,222,344)
AND CatCustom NOT LIKE '%LRR01%';

How do I deal with a passed parameter that may have an apostrophe in SQL Server?

I'm using a query within a loop in TestComplete, and each time the loop completes, the variable is updated with a new value. I want to account for the possibility of an apostrophe in the variable so I can use one query. For example:
i = 0;
while(i < companyCount)
{
result = CompanyAddress(company);
Log.Message(result);
i++;
}
'CompanyAddress' is the query I have stored in another script file, and 'company' is the variable being passed.
SELECT address FROM table WHERE name = '" + company + "';
I tried REPLACE(), but that didn't fix the problem when it got to the second iteration.
To escape apostrophe inside a SQL string you use double apostrophe:
SET #name = "Dan''s example"
But the best way is to parametrize the query, which also heps preventing SQL injection.
I incorrectly used the REPLACE() method I mentioned in my initial explanation.
I sent the variable with the single quote to the query:
var test = "agwh'waf'2";
but when I included it in the query, I used the following:
"select * from table where name = " + test.replace(/'/g, "\'\'");
This replaced single quotes in my variable with two single quotes before the query was run.

How to add a parameter to an existing stored procedure in SQL Server

I want to add a new parameter to an existing stored procedure. Body of this procedure may have been already customized by users so I can't drop and recreate it. I don't need to modify the body, just the signature.
So I thought to do a replacement of the last existing parameter by itself + the new parameter.
replace(OBJECT_DEFINITION (OBJECT_ID(id)),'#last_param varchar(max)=null','#last_param varchar(max)=null, #new_param varchar(max)=null')
It works fine if the following string is found
#last_param varchar(max)=null
but doesn't work if there is spaces in the string.
I would like to use a regex to be sure it works in all cases but I'm not sure it's possible in SQL Server.
Can you help me please ?
Thanks
SQL Server does not natively support regular expressions. You'll have to look at more manual string-analyzing with the available string functions. Something like this:
set #obDef = OBJECT_DEFINITION(OBJECT_ID(id))
set #startLastParam = PATINDEX('%#last_param%varchar%(%max%)%=%null%', #obDef)
if #startLastParam = 0 begin
-- handle lastParam not found
end else begin
set #endLastParam = CHARINDEX('null', #obDef, #startLastParam) + 4 -- 4 = len('null')
set #newDef = STUFF(#obDef, #endLastParam, 0, ', #new_param varchar(max)=null')
end
This isn't very fool-proof/safe though. PATINDEX() only gives you the same % wildcard you know from LIKE, it may match no character, it may match half the stored proc to find the word max somewhere entirely outside the signature.
So don't just run this in your customers production ;) but if you are certain about the current stored proc signature, this might just do the trick for you.

SQL Server: Concatenating WHERE Clauses. Seeking Appropriate Pattern

I want to take a poorly designed SQL statement that's embedded in C# code and rewrite it as a stored procedure (presumably), and am looking for an appropriate means to address the following pattern:
sql = "SELECT <whatever> FROM <table> WHERE 1=1";
if ( someCodition.HasValue )
{
sql += " AND <some-field> = " + someCondition.Value;
}
This is a simplification. The actual statement is quite long and contains several such conditions, some of which include INNER JOIN's to other tables if the condition is present. This last part is key, otherwise I'd probably be able to solve all of them with:
WHERE <some-condition-value> IS NULL OR <some-field> = <some-condition-value>
I can think of a few possible approaches. I'm looking for the correct approach.
Edit:
I don't want to perform concatenation in C#. I consider this a serious compromise to security.
If I understand the question properly, the idea is to replace a whole section of code in C# in charge of producing, "long hand", a specific SQL statement corresponding to a list of search criteria, by a single call to a stored-procedure which would, SQL-side, use a generic template of the query aimed at handling all allowed combinations of search criteria in a uniform fashion.
In addition to the difficulty of mapping expressions evaluated on the application-side (eg. someCondition.HasValue) to expressions evaluated on the SQL-side (eg "some-condition-value"), the solution you envision may be logically/functionally equivalent to a "hand-crafted" SQL statement, but slower and more demanding of SQL resources.
Essentially, the C# code encapsulates specific knowledge about the "physical" layout of the database and its schema. It uses this info to figure-out when a particular JOIN may be required or when a particular application-level search criteria value translate to say a SQL "LIKE" rather than an "=" predictate. It may also encaspsulate business rules such as "when the ZIP code is supplied, search by that rather than by State".
You are right to attempt and decouple the data model (the way the application sees the data) from the data schema (the way it is declared and stored in SQL), but the proper mapping needs to be done somehow, somewhere.
Doing this at the level of the application, with all the expressive power of C# as opposed to say T-SQL, is not necessarily a bad thing, provided it is done
- in a module that is independent of other features of the application
and, where practical,
- it is somewhat data/configuration-driven as so to allow small changes in the data model (say the addition of a search criteria) to be implemented by changing a configuration file, rather than plugging this in somewhere in the middle of a long series of C# conditional statements.
start with this WHERE clause:
WHERE 1=1
then append all conditions as:
AND <some-field> = " + someCondition.Value;
the optimizer will toss out the 1=1 condition and you don't have to worry about too many ANDs
EDIT based on OP's comment about not wanting to concatinate strings:
here is a very comprehensive article on how to handle this topic:
Dynamic Search Conditions in T-SQL by Erland Sommarskog
it covers all the issues and methods of trying to write queries with multiple optional search conditions
here is the table of contents:
Introduction
The Case Study: Searching Orders
The Northgale Database
Dynamic SQL
Introduction
Using sp_executesql
Using the CLR
Using EXEC()
When Caching Is Not Really What You Want
Static SQL
Introduction
x = #x OR #x IS NULL
Using IF statements
Umachandar's Bag of Tricks
Using Temp Tables
x = #x AND #x IS NOT NULL
Handling Complex Conditions
Hybrid Solutions – Using both Static and Dynamic SQL
Using Views
Using Inline Table Functions
Conclusion
Feedback and Acknowledgements
Revision History
Well you can start with
StringBuilder sb = new StringBuilder();
sb.Append("SELECT <whatever> FROM <table> WHERE 1 = 1 ");
if ( someCodition.HasValue )
{
sb.Append(" AND <some-field> = " + someCondition.Value);
}
// And so on
Will save you the trouble of putting the first WHERE - AND
[Edit]
You can also try this
Create an SP with all required parameters for the table, and write the query like this.
DECLARE #sqlStatement NVARCHAR(MAX)
#sqlStatement = " SELECT fields1, fields2 FROM TableA WHERE 1 = 1 "
if(#param1 IS NOT NULL) #sqlStatement = #sqlStatement + "AND Column1 = " + #param1
if(#param2 IS NOT NULL) #sqlStatement = #sqlStatement + "AND Column2 = " + #param2
// and so on
sp_executeSql #sqlStatement
Also you can try similar SP but with:
SELECT fields1, fields2 FROM TableA WHERE 1 = 1
AND ( ( #param1 IS NULL ) OR ( Column1 = #param1 ) )
AND ( ( #param2 IS NULL ) OR ( Column2 = #param2 ) )
this is definitely injection proof!

Resources