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.
Comments
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.
ok
did you try '2018-04-23' instead of $h ?
SELECT top 3 EFFECTIVE_START_DATE PACKAGE.SOME_TABLE_NAME
may show the expected default.
No problem in selecting from the table
Problems only when trying to insert new data to the table.
I tried yyyy-mm-dd and $h (i tried $h only when it was defined as %Date letting the Cache auto translate using %Date.LogicalToOdbc method)
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.
At the oracle db - the field type is DATE and no special format is specified for the field.
SQL shell is working (using to_date no matter if it's %Date or %String)
So what the sql shell and SMP are doing that i'm not doing in the code?
Oops. we overlapped. pls. take a look to status
I'm checking the status of prepare and there's no problem during the prepare, it's the execute that return the error.
copy+paste from the example:
status=obj.%Prepare(statement)
i status s result=obj.%Execute($zd($zdh(somedateYYYYMMDD,8),3),par2,par3,par4)
Using TO_DATE (?,'YYYYMMDD') in prepare
Executing as you said - working in the terminal, and also in the code, finally
Thank you very much
![]()
![]()
![]()
WOW! good luck.![]()
and let me have your Accepted
Through terminal couldn't make it work nomater 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
What is a definition of oracle table, what format is EFFECTIVE_START_DATE?
I understand that on Caché side it was generated as %Date but you changed it to %String? It then worked in SMP and not in Terminal?
And if you changed it back to %Date, it doesn't work in SMP?