snwoflake issue with date format in a stored procedure - snowflake-cloud-data-platform

I don't understand my issue with date format in a stored procedure call back.
create or replace procedure dailybucket()
returns varchar
language javascript
as
$$
var my_sql_command = "SELECT current_date()";
var statement1 = snowflake.createStatement( {sqlText: my_sql_command} );
var result_set1 = statement1.execute();
result_set1.next();
var column1 = result_set1.getColumnValue(1);
return column1;
$$
;
When i do SELECT current_date() i get the date format as :
2020-01-14
When i do a callback from my function call dailybucket() i get a full date ... :
Tue Jan 14 2020 00:00:00 GMT-0800 (PST)
Anyone have an idea how to retrieve data format only from function return ?

Could you try this one?
create or replace procedure dailybucket()
returns varchar
language javascript
as
$$
var my_sql_command = "SELECT to_char(current_date())";
var statement1 = snowflake.createStatement( {sqlText: my_sql_command} );
var result_set1 = statement1.execute();
result_set1.next();
var column1 = result_set1.getColumnValue(1);
return column1;
$$
;
As I understand, the JavaScript variable turns the short date to full date.

Related

SnowFlake StoredProcedure Code not working when creating dynamic statement for information_schema.columns

I am new to Snowflake, trying to create a small sp to get the row and col count of any table
SP Name :
"GET_ROW_COUNT_TESTSP"("DATABASE_NAME" VARCHAR(16777216), "SCHEMA_NAME" VARCHAR(16777216), "TABLE_NAME" VARCHAR(16777216))
Snippets from body :
var sql_command_columncount = "select COUNT (DISTINCT COLUMN_NAME) AS COLCOUNT from "+DATABASE_NAME+"."+"information_schema.columns where TABLE_CATALOG ="+''+DATABASE_NAME+''+ " and table_schema = " + ''+SCHEMA_NAME+''+ "and table_name = " + '' +TABLE_NAME+ ''+ "and column_name <> ''TESTCOLUMNNAME'' ";
var stmt2 = snowflake.createStatement(
{
sqlText: sql_command_columncount
}
);
var res2 = stmt2.execute();
res2.next();
COLCOUNT = res2.getColumnValue(1);
return COLCOUNT;
This is throwing error, tried all different single quote, not working, hard-coding of dbname,schemaname,tablename is working.
Any help is appreciated.
There is a problem with quote encapsulation on that line. The best way to address this is to use backticks to enclose your SQL string. This will allow use of single and double quotes and line breaks without having to concatenate strings. It will also allow use of template literals, which means for any variable X you can replace its literal value in a string using the syntax ${X}. Your SQL statement would look something like this:
var sql_command_columncount =
`select COUNT (DISTINCT COLUMN_NAME) AS COLCOUNT
from ${DATABASE_NAME}.information_schema.columns
where TABLE_CATALOG = '${DATABASE_NAME}
and table_schema = '${SCHEMA_NAME}'
and table_name = ${TABLE_NAME}
and column_name <> 'TESTCOLUMNNAME'
`;
I agree with the above answer, there were a few missing quotes above so corrected it and below is the working code as tested.
CREATE OR REPLACE PROCEDURE "GET_ROW_COUNT_TESTSP"("DATABASE_NAME"
VARCHAR(16777216), "SCHEMA_NAME" VARCHAR(16777216), "TABLE_NAME"
VARCHAR(16777216))
RETURNS VARCHAR
LANGUAGE JAVASCRIPT
EXECUTE AS OWNER
AS
$$
var sql_command_columncount = `select COUNT (DISTINCT COLUMN_NAME)
AS COLCOUNT from ${DATABASE_NAME}.information_schema.columns where
TABLE_CATALOG = '${DATABASE_NAME}' and table_schema =
'${SCHEMA_NAME}'
and table_name = '${TABLE_NAME}' and column_name <>
'TESTCOLUMNNAME'
`
var stmt2 = snowflake.createStatement(
{
sqlText: sql_command_columncount
}
);
var res2 = stmt2.execute();
res2.next();
COLCOUNT = res2.getColumnValue(1);
return COLCOUNT;
$$;
Cleaner version without using ticks and used double quote and parameterized ...
create or replace procedure getrowcounts_1(DATABASE_NAME VARCHAR, SCHEMA_NAME VARCHAR, TABLE_NAME VARCHAR)
RETURNS VARCHAR LANGUAGE JAVASCRIPT AS $$
var sql_command="Select row_count from "+DATABASE_NAME +"."+SCHEMA_NAME + "."+ "TABLES WHERE TABLE_NAME="+"'"+TABLE_NAME+"'";
var stmt = snowflake.createStatement(
{
sqlText: sql_command
}
);
var res = stmt.execute();
res.next();
COLCOUNT = res.getColumnValue(1);
return COLCOUNT;
$$;
Output:

Stored procedure handling multiple SQL statements in Snowflake

I'm creating a stored procedure in Snowflake that will eventually be called by a task.
However I'm getting the following error:
Multiple SQL statements in a single API call are not supported; use one API call per statement instead
And not sure how approach the advised solution within my Javascript implementation.
Here's what I have
CREATE OR REPLACE PROCEDURE myStoreProcName()
RETURNS VARCHAR
LANGUAGE javascript
AS
$$
var rs = snowflake.execute( { sqlText:
`set curr_date = '2015-01-01';
CREATE OR REPLACE TABLE myTableName AS
with cte1 as (
SELECT
*
FROM Table1
where date = $curr_date
)
,cte2 as (
SELECT
*
FROM Table2
where date = $curr_date
)
select * from
cte1 as 1
inner join cte2 as 2
on(1.key = 2.key)
`
} );
return 'Done.';
$$;
You could write your own helper function(idea of user: waldente):
this.executeMany=(s) => s.split(';').map(sqlText => snowflake.createStatement({sqlText}).execute());
executeMany('set curr_date = '2015-01-01';
CREATE OR REPLACE TABLE ...');
The last statement should not contain ; it also may fail if there is ; in one of DDL which was not intended as separator.
You can't have:
var rs = snowflake.execute( { sqlText:
`set curr_date = '2015-01-01';
CREATE OR REPLACE TABLE myTableName AS
...
`
Instead you need to call execute twice (or more). Each for a different query ending in ;.

Execution error in store procedure SQL compilation error: invalid identifier 'TEST3' At Statement.execute

I have created below stored Procedure but getting error while parsing VAL in where clause, i have tried double quotes " and backstick ` as well
create or replace TABLE T1 (
COL VARCHAR(16777216)
);
insert into t1 values ('test1');
insert into t1 values ('test2');
insert into t1 values ('test3');
create or replace procedure ifcopied(val varchar)
returns varchar
language javascript
execute as caller
as
$$
sql_command = "select * from t1 where col = " + VAL;
var stmt = snowflake.createStatement({sqlText:sql_command});
var res = stmt.execute();
res.next();
row_status = res.getColumnValue(1);
return row_status
$$;
call ifcopied('test3')
;
getting below error
Execution error in store procedure IFCOPIED: SQL compilation error: error line 1 at position 29 invalid identifier 'TEST3' At Statement.execute, line 4 position 50
Execution error in store procedure IFCOPIED: SQL compilation error: error line 1 at position 29 invalid identifier 'TEST3' At Statement.execute, line 4 position 50
In addition to what Gokhan has you can also perform it this way.
sql_command = `select * from t1 where col = '${VAL}';`
This keeps down on your use of concatenation as well as allows you to see the variables in line.
You need to add single quotes or use bind variables:
create or replace procedure ifcopied(val varchar)
returns varchar
language javascript
execute as caller
as
$$
sql_command = "select * from t1 where col = '" + VAL + "'";
var stmt = snowflake.createStatement({sqlText:sql_command});
var res = stmt.execute();
res.next();
row_status = res.getColumnValue(1);
return row_status
$$;
Recommend version with using bind variables:
create or replace procedure ifcopied(val varchar)
returns varchar
language javascript
execute as caller
as
$$
sql_command = "select * from t1 where col = ?";
var stmt = snowflake.createStatement({sqlText:sql_command, binds:[ VAL ]});
var res = stmt.execute();
res.next();
row_status = res.getColumnValue(1);
return row_status
$$;

Snowflake Database: Want to use value from a column in a table as a column name in select statement for another table

I am using snowflake
CREATE OR REPLACE PROCEDURE test1(TBLNM varchar)
RETURNS VARCHAR(16777216) not null
LANGUAGE JAVASCRIPT
$$
var sql_cmd = "SELECT col1 FROM TBLNM ;
var ins = `insert into tabl2 (column1) SELECT :1
FROM table1 `
;
var stmt = snowflake.createStatement(
{
sqlText: sql_cmd
}
);
var res = stmt.execute();
while (res.next()) {
var column1 = res.getColumnValue(1);
ins_stmt=snowflake.execute(
{
sqlText: ins,
binds: [column1]
}
);
}
$$
for eg in TBLNM i have 3 rows values like
col1
name
lastname
Grade
and what i am trying here is , the value 'name' from TBLNM should be treated as column name in select statement of table 1 to fetch the values
insert into tabl2 (column1) SELECT name FROM table1.
this should insert name of person in table like :
column1
Peter
Parker
5th
but it is inserting 'name' as a value. It is treating 'name' as a text.
column1
Name
Lastname
Grade
Please help me out to treat bind variable as column name rather then a string.
You can use Javascript concatenation rather than bind variables.
This works for me:
CREATE OR REPLACE PROCEDURE test1(TBL_NAME varchar, COL_NAME varchar)
RETURNS VARCHAR(16777216) not null
LANGUAGE JAVASCRIPT
AS
$$
var stmt = snowflake.createStatement(
{
sqlText: `SELECT ` + COL_NAME + ` FROM ` + TBL_NAME
});
var res = stmt.execute();
while (res.next()) {
var column1 = res.getColumnValue(1);
var ins_stmt = snowflake.createStatement(
{
sqlText: `INSERT INTO table2 SELECT ` + column1 + ` FROM table1`
});
var res_ins = ins_stmt.execute();
}
$$;
call test1('store', 'col1');
Some examples also present here:
https://community.snowflake.com/s/article/Snowflake-Introduces-Javascript-Stored-Procedures
Regards,

Passing multiple params to stored procedure

I trigger stored procedure and pass parameters from Visual Studio to SQL Server stored procedure.
Here is code:
var cId = new SqlParameter("#clientId", clientId);
var result = _context.Database.SqlQuery<DamageEventsDTL>("SPDamageEventsDTL #clientId", cId );
But I need to pass multiple parameters (int, DateTime and list of integers).
Here how I do it:
int clientId = 5;
DateTime date = new DateTime("2016-07-01");
List<int> list= new List<int>(new int[] { 2, 3, 5 });
var cId = new SqlParameter("#clientId", clientId);
var dateEvents = new SqlParameter("#date", date);
var freqEvents = new SqlParameter("#list ", list );
var result = _context.Database.SqlQuery<DamageEventsDTL>("SPDamageEventsDTL #cId, #date, #list ", cId, dateEvents, list);
But it seems to be wrong way.
Any idea what I do wrong here?
you can also use an XML to send parameters to SQL, like this:
USE tempdb
GO
DECLARE #Element XML;
SET #Element='
<SavedOrderElement>
<Data>
<Age>5</Age>
<Nit>46546546546</Nit>
<Name>Jeff</Name>
<LastName>Thalliens</LastName>
<Email>VerizonBoughtYahoo#yahoo.com</Email>
<PokemonGo>Nothing</PokemonGo>
</Data>
</SavedOrderElement>' ;
;WITH ElementSavedOrders
AS
(
SELECT
CAST(c.query('data(Age)') AS VARCHAR(50)) as Age
,CAST(c.query('data(Nit)') AS VARCHAR(50)) as Nit
,CAST(c.query('data(Name)') AS VARCHAR(50)) as Name
,CAST(c.query('data(LastName)') AS VARCHAR(50)) as LastName
,CAST(c.query('data(Email)') AS VARCHAR(100)) as Email
,CAST(c.query('data(PokemonGo)') AS VARCHAR(100)) as PokemonGo
FROM #Element.nodes('SavedOrderElement/*') as T(c)
)
SELECT * FROM ElementSavedOrders

Resources