Snowflake Tasks causing error in timezone in queries - stored-procedures

I am running a simple insert query inside a stored procedure with to_timeatamp_ntz("column value") along with other columns.
This works fine when I am running it with the snowflake UI and logged in with my account.
This works fine when I am calling it using python scripts from my visual studio instance.
The same stored procedure fails when it is being called by a scheduled task.
I am thinking if it has something to do with the user's timezone of 'System' vs my time zone.
Execution error in store procedure LOAD_Data(): Failed to cast variant
value "2019-11-27T13:42:03.221Z" to TIMESTAMP_NTZ At
Statement.execute, line 24 position 57
I tried to provide timezone as session parameters in task and in the stored proc but does not seem to be addressing the issue. Any ideas?

I'm guessing (since you didn't include the SQL statement that causes the error) that you are trying to bind a Date object when creating a Statement object. That won't work.
The only parameters you can bind are numbers, strings, null, and the special SfDate object that you can only get from a result set (to my knowledge). Most other parameters must be converted to string using mydate.toJSON(), JSON.stringify(myobj), etc., before binding, eg:
var stmt = snowflake.createStatement(
{ sqlText: `SELECT :1::TIMESTAMP_LTZ NOW`, binds: [(new Date).toJSON()] }
);
Date object errors can be misleading, because Date objects causing an error can be converted and displayed as strings in the error message.

I found the issue:
my Task was using a copy paste effect similar to this:
CREATE TASK TASK_LOAD_an_sp
WAREHOUSE = COMPUTE_WH
TIMEZONE = 'US/Eastern'
SCHEDULE = 'USING CRON 0/30 * * * * America/New_York'
TIMESTAMP_INPUT_FORMAT = 'YYYY-MM-DD HH24'
AS
Call LOAD_an_sp();
The Timestamp input format was causing this.

Related

thingsboard rulechain - filter script node to check if metadata timestamp is greater than server timestamp

I have created an asset variable with a timestamp attribute (dateTo) and would like to compare this to the current server time.
Ho do I get the server/system time of the Thingsboard. TBEL documentation states that "we have added Date class that you are able to use without the package name" so I should be able to get the server time with:
Date
Testing in the Test Filter Function doesn't error while using:
return Date > metadata.dateTo;
But does not assess correctly (changing the value around generates a False result either way).
Each metadata field has a string type, instead of integer as expected. So before comparison you have to convert metadata.dateTo to integer:
return Date.now() > +metadata.dateTo;

Snowflake Procedure (Assigning a value to the Variable in Task)

Would you please tell me how to assign a value to the variable on the Task? Here's the detailed scenario of what I'm trying to accomplish and what the error is.
To get the latest query_id of the below SQL statement, I am creating the following function.
CREATE OR REPLACE FUNCTION rejected_records_queryid()
RETURNS varchar
AS 'select query_id from snowflake.account_usage.query_history where QUERY_TEXT LIKE \'select 1, 2%\' AND EXECUTION_STATUS=\'SUCCESS\' order by START_TIME desc limit 1';
If I run this manually, the function works perfectly,
set qid = rejected_records_queryid();
Session variable value:
select $qid;
Please refer attached screenshot for the output.
Pic1
However, if I use the Task, the return values of the function will not be assigned to the session variable,
CREATE OR REPLACE TASK rejected_records_queryid1
WAREHOUSE = COMPUTE_WH
SCHEDULE = '1 MINUTE'
AS
set qid2 = rejected_records_queryid();
Change the task mode to resume,
ALTER TASK rejected_records_queryid1 RESUME;
The following error message appears after I check the value of the qid2 after Task run,
SQL compilation error: error line 1 at position 7 Session variable '$QID2' does not exist
Attached screenshot for the error message In order to use it in the below sql, I need the qid2 value to be assigned from the Task,
select * from table(result_scan($qid2))
Pic2
I would appreciate any help on how to assign the value to the variable in TASK or any other workarounds.

Inserting name into database, getting korean signs as output

Trying to insert simple xml file with one row in IIB with simple message flow into Oracle XE DB. Message flow works fine and inserts data into database, but data written in db is different from starting data. For example, as I'm trying to insert my name "Dino" I'd get Korean/Japanese/Chinese signs in return.
I've tried changing XML formats thinking there might be problem, but I suppose it has to do with encoding.
Input:
Output in DB:
This is how my compute node looks like:
CREATE COMPUTE MODULE SimpleDB_mf_Compute
CREATE FUNCTION Main() RETURNS BOOLEAN
BEGIN
CALL CopyMessageHeaders();
-- CALL CopyEntireMessage();
INSERT INTO Database.dkralj.emp VALUES(InputRoot.XMLNSC.emp.name);
SET OutputRoot.XMLNSC.DBINSERT.STATUS='SUCCESS';
RETURN TRUE;
END;
CREATE PROCEDURE CopyMessageHeaders() BEGIN
DECLARE I INTEGER 1;
DECLARE J INTEGER;
SET J = CARDINALITY(InputRoot.*[]);
WHILE I < J DO
SET OutputRoot.*[I] = InputRoot.*[I];
SET I = I + 1;
END WHILE;
END;
CREATE PROCEDURE CopyEntireMessage() BEGIN
SET OutputRoot = InputRoot;
END;
END MODULE;
Looking at the IBM documentation for the INSERT statement in ESQL it might be worth trying.
INSERT INTO Database.dkralj(NAME) VALUES(InputRoot.XMLNSC.emp.name);
If weird things are still happening then I'd try a string constant to avoid any issues with character coding in the input message.
INSERT INTO Database.dkralj(NAME) VALUES('TheEmpValue');
Before this statement in your code
SET OutputRoot.XMLNSC.DBINSERT.STATUS='SUCCESS';
You should check for success or otherwise by using the inbuilt SQLSTATE, SQLCODE, SQLERRORTEXT to check the result of your call.
IF NOT ((SQLCODE = 0) OR (SQLSTATE = '01000' AND SQLNATIVEERROR = 8153)) THEN
-- Do something about the error.
-- The check of SQLSTATE and SQLNATIVEERROR covers warnings
-- The 8153 is for Microsoft SQL Server other databases may use a different value
END IF;
Also check the codepages aka CodedCharSetId of the source system data, the message in IIB and the default codepage of the database.
Use mqsicvp MYBROKER -n ODBC_DB_NAME to get other details about the connection you need to use -n to get the details.
Use something like DBeaver to add some data. Have a look at the datatype specified for the field.
As per your comment below and my response here is an example of a PASSTHRU statement. Note the use of the ? to avoid SQL Injection.
PASSTHRU('SELECT RTRIM(A.EMPLID) AS EMPLID,
RTRIM(A.ADDRESS_TYPE) AS ADDRESS_TYPE,
RTRIM(A.ADDR_TYPE_DESCR) AS ADDR_TYPE_DESCR,
CAST(RTRIM(A.EFFDT) AS DATE) AS EFFDT,
RTRIM(A.EFF_STATUS) AS EFF_STATUS,
RTRIM(A.ADDRESS1) AS ADDRESS1,
RTRIM(A.ADDRESS2) AS ADDRESS2,
RTRIM(A.ADDRESS3) AS ADDRESS3,
RTRIM(A.ADDRESS4) AS ADDRESS4,
RTRIM(A.CITY) AS CITY,
RTRIM(A.STATE) AS STATE,
RTRIM(A.POSTAL) AS POSTAL
FROM ADDRESS_VW AS A
WHERE UPPER(A.EMPLID) = ?') VALUES(AggrRef.EmployeeID)

Getting an error while inserting data using stored procedure in mvc entity framework

I'm getting an error
converting data type nvarchar to datetime.
Where I did mistake?
var exec = db.Database.ExecuteSqlCommand("sp_InsertTicketChat #TicketId,
#FullName, #Description,
#LastCorrespondanceBy,#LastCorrespondanceOn",
new SqlParameter("#TicketId", TicketId),
new SqlParameter("#FullName", FullName),
new SqlParameter("#Description", Description),
new SqlParameter("#LastCorrespondanceBy", FullName),
new SqlParameter("#LastCorrespondanceOn",
DateTime.Now.ToString())
);
This is my stored procedure through which I want to insert data. What can I do ?
INSERT INTO tblTicketChat
(
TicketId,
FullName,
[Description],
LastCorrespondanceOn,
LastCorrespondanceBy
)
VALUES
(
#TicketId,
#FullName,
#Description,
GETDATE(),
#LastCorrespondanceBy)
Now I got the root cause of the issue you were facing.
Ideally, DateTime.Now.ToString() should have got converted to SQL Server Datetime data type when being assigned to the #LastCorrespondanceOn parameter of your stored procedure but it threw an exception.
The reason is date time format settings of your operating system.
The thing is when you perform DateTime.Now.ToString() in your C# language based client code it takes the default settings of date time format from your operating system. Look at the date time format currently set on my windows 10 box:
Due to this setting the code DateTime.Now.ToString() emits 27-07-2017 18:07:37. The output you're seeing is dd-MM-yyyy format.
Now this dd-MM-yyyy date format is not recognizable by SQL Server as per your default language settings.
SQL Server can recognize two date time formats when sent as string from client side
International date format yyyy-MM-dd also known as ISO 8601 .
Date format controlled by user login's dateformat setting. You can run dbcc useroptions command to see the value of setting. For me it is set to mdy
Due to this mismatch in the date time format being sent by your C# code (because of your operating system) and what SQL server can parse, you faced the issue.
When you did the conversion explicitly by date.ToString("yyyy-MM-dd"); you simply aligned it ISO 8601 international date time format supported by SQL Server so it started to work.
The default date time format (ISO 8601) of SQL Server is a configuration of the collation you are using currently which you can check in your SQL Server instance properties as shown below:
It is strongly recommended that you should always use SQL's date time format when passing it in string format as mentioned in this thread.
So you can solve your problem in three ways:
Change the default date format of your OS to align it to SQL Server (Not recommended). It will never be feasible on all client computers where your application runs.
Use custom date format while calling ToString method as you have done to align it to one of the formats supported by SQL Server. Best format is ISO 8601 format which you've used.
Don't convert it to string. Just pass the date time value as is.
var exec = db.Database.ExecuteSqlCommand("sp_InsertTicketChat #TicketId,
#FullName, #Description,
#LastCorrespondanceBy,#LastCorrespondanceOn",
new SqlParameter("#TicketId", TicketId),
new SqlParameter("#FullName", FullName),
new SqlParameter("#Description", Description),
new SqlParameter("#LastCorrespondanceBy", FullName),
new SqlParameter("#LastCorrespondanceOn",
DateTime.Now) //Don't call .ToString here
);
Approach # 3 is the best deal. More details here as to why you shouldn't use strings but the date time data type while dealing with SQL Server datetime columns.
I solve this issues by using MSSQL string formatted (dd-MM-yyyy) in my storedprocedure
I solved this issue by doing some changes.
DateTime date = DateTime.Now;
string strDateTime = date.ToString("yyyy-MM-dd");
var exec = db.Database.ExecuteSqlCommand("sp_InsertTicketChat #TicketId, #FullName, #Description, #LastCorrespondanceOn, #LastCorrespondanceBy",
new SqlParameter("#TicketId", TicketId),
new SqlParameter("#FullName", FullName),
new SqlParameter("#Description", Description),
new SqlParameter("#LastCorrespondanceBy", "raza"),
new SqlParameter("#LastCorrespondanceOn", strDateTime)
);

How to use Slickgrid Formatters with MVC

I am working on a first Slickgrid MVC application where the column definition and format is to be stored in a database. I can retrieve the list of columns quite happily and populate them until I ran into the issue with formatting of dates. No problem - for each date (or time) column I can store a formatter name in the database so this can be retrieved as well. I'm using the following code which works ok:
CLOP_ViewColumnsDataContext columnDB = new CLOP_ViewColumnsDataContext();
var results = from u in columnDB.CLOP_VIEW_COLUMNs
select u;
List<dynColumns> newColumns = new List<dynColumns>();
foreach(CLOP_VIEW_COLUMN column in results)
{
newColumns.Add(new dynColumns
{
id = column.COLUMN_NUMBER.ToString(),
name = column.HEADING.Trim(),
field = column.VIEW_FIELD.Trim(),
width = column.WIDTH,
formatter = column.FORMATTER.Trim()
});
}
var gridColumns = new JavaScriptSerializer().Serialize(newColumns);
This is all fine apart from the fomatter. An example of the variable gridColumns is:
[{"id":"1","name":"Date","field":"SCHEDULED_DATE","width":100,"formatter":"Slick.Formatters.Date"},{"id":"2","name":"Carrier","field":"CARRIER","width":50,"formatter":null}]
Which doesn't look too bad however the application the fails with the error Microsoft JScript runtime error: Function expected in the slick.grid.js script
Any help much appreciated - even if there is a better way of doing this!
You are assigning a string to the formatter property, wich is expected to be function.
Try:
window["Slick"]["Formatters"]["Date"];
But i really think you should reconsider doing it this way and instead store your values in the db and define your columns through code.
It will be easier to maintain and is less error prone.
What if you decide to use custom editors and formatters, which you later rename?
Then your code will break or you'll have to rename all entries in the db as well as in code.

Resources