Question
· Apr 23, 2018

I can insert a new record through the SMP but not through code

Hi,

The following sql statement is working through the SMP but couldn't make it work through the code.

The table is a linked table to oracle db.

Tried to change the date property in the linked table class from %Date to %String and also tried using %SQL.Statement and %Library.ResultSet

this work through SMP:

INSERT INTO PACKAGE.SOME_TABLE_NAME

(EFFECTIVE_START_DATE,MORE,DATA,HERE)

VALUES (to_date ('2018-04-01','yyyy-mm-dd'),123,456,789)

In the code i'm using '?' in the statement for the parameters.

So in the code it's go something like this (where the to_date is in the sql statement):

Set statement="INSERT INTO PACKAGE.SOME_TABLE_NAME (EFFECTIVE_START_DATE,MORE,DATA,HERE) VALUES (to_date (?,'yyyy-mm-dd'),?,?,?)"

s obj=##class(%SQL.Statement).%New()

s status=obj.%Prepare(statement)

i status s result=obj.%Execute($zd($zdh(somedateYYYYMMDD,8),3),par2,par3,par4)

or this one (where the to_date is in the execute)

Set statement="INSERT INTO PACKAGE.SOME_TABLE_NAME (EFFECTIVE_START_DATE,MORE,DATA,HERE) VALUES (?,?,?,?)"

s obj=##class(%SQL.Statement).%New()

s status=obj.%Prepare(statement)

i status s result=obj.%Execute("to_date ('"_$zd($zdh(somedateYYYYMMDD,8),3)_"','yyyy-mm-dd')",par2,par3,par4)

As you can see i tried putting the to_date in the Prepare statement and it didn't work and also in the execute (in the parameters) it didn't work.

Discussion (14)2
Log in or sign up to continue

The change from %Date to %String influences image of your target table
and may affect implicit ODBC Data transmission that converts eg. +$h to YYY-MM-DD format !

once your data is a %Date again this should do it:
...... VALUES (?,?,?,?)
%Execute($zdh(somedateYYYYMMDD,8),par2,par3,par4)

If you test in SMP you have to check if you are in ODBC, Logical or Display mode.
with TO_DATE() you just overrule this as string are the same in any mode.

For ODBC the date is always 2018-04-25
For Display it's 04/23/2018 or 23.04.2018 depending on your local setting
For Logial it is always 64761 (+$h)

Still not working in the code, at the SMP it worked in every mode Display/Logical/ODBC. isn't the mode affect only on select statements? At the code i set the property back to %Date, and the sql statement and execute without the to_date, at the execute just converted to $h as you mentioned and i'm getting error [Oracle][ODBC][Ora]ORA-01861: literal does not match format string.

At the Caché side it was generated as %Date using the link table wizard, through the SMP it worked with to_date when it was %Date and worked also after i changed it to %String.

Through terminal couldn't make it work no mater what i tried, not when it is %Date and using $h without to_date nor when it is %String and translating the date to yyyy-mm-dd with or without to_date (at prepare or at execute).

I also tried using ##class(Package.SomeClassName).%New() and %Save()  and it also return ORA-01861 error ($h when %Date and yyyy-mm-dd when %String).

Also %String with %New/Save with "to_string ('"_FormattedDate_"','yyyy-mm-dd')" as the field value returned ORA-01858 error.

Don't know the table/field definition/format at the oracle db - hope to get this info soon.

Through terminal couldn't make it work no mater what i tried, not when it is %Date and using $h without to_date nor when it is %String and translating the date to yyyy-mm-dd with or without to_date (at prepare or at execute).

Did you also try SQL shell from terminal ?  (it should act like SMP)
SAMPLES>Do $system.SQL.Shell()
SAMPLES>>INSERT INTO .......

Also: have you ever checked status  ?   to see if  %Prepare was OK ?

after:

s status=obj.%Prepare(statement)

do $system.OBJ.DisplayError(status)

It's hidden in your example

doc for ORA-01861
describes the TO_Date issue very detailed

https://www.techonthenet.com/oracle/errors/ora01861.php

Your problem seems to be strictly related that the value you use and its description in TO_DATE don't match.

So TO_DATE(?,'YYYYMMDD') in Prepare
should work with 
    s result=obj.%Execute(20180425,par2,par3,par4)

It's a little bit less transformations