Retrieving Data From Returned Oracle Timestamp Column - oracle11g

We have a ColdFusion 8 (Linux) application that uses an Oracle timestamp. We just converted to Oracle 11g from 10g and we're now using Oracle's thin client on the data sources. We're getting an error in the application where a timestamp column is selected.
It seems as though an object of class oracle.sql.TIMESTAMP is being returned. I verified this by dumping the contents of the column. Sure enough, it gives me a break down of the object's methods and their return types. But, I can't seem to be able to interface with this object directly:
<cfquery name="getstuff" ...>
SELECT timestampfld ...
FROM myTable
</cfquery>
getstuff.timestampfld contains an object. But, doing this:
<cfoutput query="getstuff">
#timestampfld.stringValue()#
#timestampfld.dateValue()#
</cfoutput>
produces the error that says those methods can't be found. How can I get at the data held in that object?
Update from comments:
When I take column value and apply the DateFormat( timestampfld, "dd.mm.yyyy" ) function to it. The CF error is
"The value class oracle.sql.timestamp cannot be converted to a date".
When I perform <cfoutput>, I get the class definition.
In the retrieved column, I seem to be getting an object instead of a string. When I cfdump the column, I get OBJECT OF oracle.sql.TIMESTAMP. The dump lays out the methods and fields available. When I cfoutput that same variable, a string is displayed. When I try to perform a DataFormat() on the variable, it complains that its not a date.

I just happened to stumble over this error during my development. I had it in the past and long forgotten since.
I know of two ways to mitigate:
The first is according to an answer of a question regarding the same error message in a different context.
One would add the following to the jvm.config file
-Doracle.jdbc.J2EE13Compliant=true
The second is not to return an Oracle TIMESTAMP column but CAST it do DATE, first, like
<cfquery name="getstuff" ...>
SELECT CAST( timestampfld as DATE ) timestampfld
FROM myTable
</cfquery>
I'm not satisfied with either, to be honest. When the JVM argument is forgotten, the software crashes. The CAST, on the other hand, may influence how the SQL works.

Related

How to implement INSERT where not exists for ORACLE in Mule4

I am trying to implement a use-case in Mule4 where a tour needs to be assigned to a user if it has not already been assigned.
I was hoping that I could implement it using Mule db:insert component and using INSERT WHERE NOT EXISTS SQL script as below.
INSERT INTO TL_MAPPING_TOUR(TOURNO,TLID,SYSTEM) select :tourno,:tlid,:system from DUAL
where not exists(select * from TL_MAPPING_TOUR where (TOURNO=:tourno and TLID=:tlid and SYSTEM=:system))
However, this is resulting in Mule Exception
Message : ORA-01722: invalid number
Error type : DB:BAD_SQL_SYNTAX
TL_MAPPING_TOUR table has an id column (Primary Key), but that is auto-generated by a sequence.
The same script, modified for running directly in SQL developer, as shown below, is working fine.
INSERT into TL_MAPPING_TOUR(TOURNO,TLID,SYSTEM)
select 'CLLO001474','123456789','AS400'
from DUAL
where not exists(select * from TL_MAPPING_TOUR where (TOURNO='CLLO001474' and TLID='123456789' and SYSTEM='AS400'));
Clearly Mule db:insert component doesn't like the syntax, but it's not very clear to me what is wrong here. I can't find any INSERT WHERE NOT EXISTS example implementation for the Mule4 Database component either.
stackoverflow page https://stackoverflow.com/questions/54910330/insert-record-into-sql-server-when-it-does-not-already-exist-using-mule directs to page not found.
Any idea what is wrong here and how to implement this in Mule4 without using another Mule4 db:select component before db:insert?
I don't know "mule4", but this:
Message : ORA-01722: invalid number
doesn't mean that syntax is wrong (as you already tested it - the same statement works OK in another tool).
Cause: You executed a SQL statement that tried to convert a string to a number, but it was unsuccessful.
Resolution:
The option(s) to resolve this Oracle error are:
Option #1: Only numeric fields or character fields that contain numeric values can be used in arithmetic operations. Make sure that all expressions evaluate to numbers.
Option #2: If you are adding or subtracting from dates, make sure that you added/substracted a numeric value from the date.
In other words, it seems that one of columns is declared as NUMBER, while you passed something that is a string. Oracle performed implicit conversion when you tested the statement in SQL Developer, but it seems that mule4 didn't and hence the error.
The most obvious cause (based on what you posted) is putting '123456789' into TLID as other values are obviously strings. Therefore, pass 123456789 (a number, no single quotes around it) and see what happens. Should work.
SQL Developer is too forgiving. It will convert string to numbers and vise versa automatically when it can. And it can a lot.
Mulesoft DB connector tries the same but it is not as succefule as native tools. Pretty often it fails to convert, especially on dates but this is not your case.
In short - do not trust too much data sense of Mulesoft. If it works - great! Otherwise try to eliminate any intelligence from it and do all conversions in the query and better from the string. Usually number works fine but if doesn't - use to_number function to mark properly that this is the number.
More about this is here https://simpleflatservice.com/mule4/AvoidCoversionsOrMakeThemNative.html

SQLite, Update Statement using DateTime

I have been trying to update a datetime column using the following SQL Statement:
UPDATE HistoricData SET RecordDate=DATETIME(RecordDate,'60 minutes') WHERE DataStreamID=1 AND TimeFrameID=5
However, I keep getting the following error message:
NOT NULL Constraint Failed: HistoricData.RecordDate
If you could recommend the appropriate change to get this working, I would very much appreciate it.
I will attempt to attach a sample schema and data:
Table Data
Table Schema
After inspecting your DML, my only remaining concern was the datetime format you have in your table. I tried updating such a value as you did, and guess what, it returns NULL: http://sqlfiddle.com/#!7/f4651/10 Why? Because your strings (do notation) are not valid ISO-8601 strings. You probably need to simply replace the dots with dashes before updating (http://sqlfiddle.com/#!7/f4651/11).

Delphi - ClientDataSet SQL calculated field causing "Invalid field type" error at runtime [duplicate]

Using Delphi 10.2, SQLite and Teecharts. My SQLite database has two fields, created with:
CREATE TABLE HistoryRuntime ('DayTime' DateTime, Device1 INTEGER DEFAULT (0));
I access the table using a TFDQuery called qryGrpahRuntime with the following SQL:
SELECT DayTime AS TheDate, Sum(Device1) As DeviceTotal
FROM HistoryRuntime
WHERE (DayTime >= "2017-06-01") and (DayTime <= "2017-06-26")
Group by Date(DayTime)
Using the Field Editor in the Delphi IDE, I can add two persistent fields, getting TheDate as a TDateTimeField and DeviceTotal as a TLargeIntField.
I run this query in a program to create a TeeChart, which I created at design time. As long as the query returns some records, all this works. However, if there are no records for the requested dates, I get an EDatabaseError exception with the message:
qryGrpahRuntime: Type mismatch for field 'DeviceTotal', expecting: LargeInt actual: Widestring
I have done plenty of searching for solutions on the web on how to prevent this error on an empty query, but have had not luck with anything I found. From what I can tell, SQLite defaults to the wide string field when no data is returned. I have tried using CAST in the query and it did not seem to make any difference.
If I remove the persistent fields, the query will open without problems on an empty return set. However, in order to use the TeeChart editor in the IDE, it appears I need persistent fields.
Is there a way I can make this work with persistent fields, or am I going to have to throw out the persistent fields and then add the TeeChart Series at runtime?
This behavior is described in Adjusting FireDAC Mapping chapter of the FireDAC's SQLite manual:
For an expression in a SELECT list, SQLite avoids type name
information. When the result set is not empty, FireDAC uses the value
data types from the first record. When empty, FireDAC describes those
columns as dtWideString. To explicitly specify the column data type,
append ::<type name> to the column alias:
SELECT count(*) as "cnt::INT" FROM mytab
So modify your command e.g. this way (I used BIGINT, but you can use any pseudo data type that maps to a 64-bit signed integer data type and is not auto incrementing, which corresponds to your persistent TLargeIntField field):
SELECT
DayTime AS "TheDate",
Sum(Device1) AS "DeviceTotal::BIGINT"
FROM
HistoryRuntime
WHERE
DayTime BETWEEN {d 2017-06-01} AND {d 2017-06-26}
GROUP BY
Date(DayTime)
P.S. I did a small optimization by using BETWEEN operator (which evaluates the column value only once), and used an escape sequence for date constants (which, in real you replace by parameter, I guess; so just for curiosity).
This data type hinting is parsed by the FDSQLiteTypeName2ADDataType procedure that takes and parses column name in format <column name>::<type name> in its AColName parameter.

Oracle 11g SQL loader, time format issue

I am trying to load a .csv file using SQL loader. I get this error message on a column that should store time column:
column TIME.ORA-01843: not a valid month
In my .csv file time has the format HH:MM:SS but I can't understand why Oracle does not recognise it.
Using the command select * from nls_session_parameters; I see that the default time format is HH24.MI.SSXFF. I tried to change the time separator in my csv file but I got the same error result.
I have a very simple control file, that looks like below.
LOAD DATA
INFILE Cycling_Accidents0512.csv
INTO TABLE CYCLING_ACCIDENTS
FIELDS TERMINATED BY ','
(ID,
ACC_ID,
OSGB_EASTING,
OSGB_NORTHING,
WGS_LONG,
WGS_LAT,
POLICE_FORCE,
ACC_SEVERITY,
NUM_VEI,
NUM_CAS,
ACC_DATE,
DAY_WEEK,
TIME,
LOC_AUTH_DIS,
LOC_AUTH_HIGH,
FST_ROAD_CLASS,
FST_ROAD_NUMBER,
ROAD_TYPE,
SPEED_LIMIT,
JUNCT_DETAIL,
JUNCT_CONTROL,
SND_ROAD_CLASS,
SND_ROAD_NUM,
PED_HUM,
PED_PHY,
LIGHT_COND,
WEATH_COND,
ROAD_SUR_COND,
SPEC_COND,
CARR_HAZARDS,
URB_RUR,
POLICE_ATT,
LSOA_ACC_LOC,
VEI_TYPE)
If someone of you can help me to modify the control file in order to make the time format acceptable to Oracle, that would be appreciated. I tried to look up on other web resources but I haven't found anything that could help.
Thanks!
You mentioned querying the session NLS parameters, but the value you showed appears to be NLS_TIME_FORMAT, which is only used internally.
Oracle doesn't have a time-only type, so your field is presumably actually a DATE type (or possibly TIMESTAMP). The values in the column will have a date part, even if you ignore it.
SQL*Loader will use NLS_DATE_FORMAT to interpret the data file value for a DATE field. If that is DD/MM/YYYY then it would liberally interpret a value like 22:41:17 as the 22nd day of the 41st month - hence your error - in the year 17.
You can specify the date format model in the control file:
TIME DATE 'HH24:MI:SS',
The value in the table would have that time, on the first day of the current month.
The SQL*Loader documentation does refer to a TIME data type which I have never seen used, and I can't find any references to it anywhere, including MOS. A quick bit of experimentation hasn't helped. If I make the control file entry:
TIME TIME,
... then the record is rejected with ORA-00933: SQL command not properly ended. The log file also shows the data type as DATETIME HH24.MI.SSXFF, which looks related to the NLS_TIME_FORMAT value. I haven't found a way to make it accept that. If I change the column definition from DATE to TIMESTAMP then I get a different error, ORA-00904: "TO_TIME": invalid identifier, which is even stranger. It almost looks like these data types are defined in SQL*Loader for future use. (This discussion suggests they thought about adding TIME as a database type in 10g, but obviously can't verify that. And this is in the SQL*Loader reference at least back to 9i).

L2Entities, stored procedure and mapping

Finally checked out L2E framework and ran into problems almost instantly.
Yeah, i know... i should read some books before.
Situation:
entity with props -> id and name.
entity is mapped to table, which has id and name columns.
sproc, which returns ONLY id column.
Problem:
ObjectResult<MyProp> result = _container.MyStoredProcedure(uberParameter);
Calling this will cause an error
[guilty method goes here] threw exception:
System.Data.EntityCommandExecutionException: The data reader is incompatible with the specified 'DataBase.MyPropTableObject'. A member of the type, 'name', does not have a corresponding column in the data reader with the same name..
Problem #2:
Can`t "just return" that field, cause that column has XML data type, but sproc uses fancy select statements, which causes:
Msg 421, Level 16, State 1, Line 1
The xml data type cannot be selected as DISTINCT because it is not comparable.
Question:
Is it possible to exclusively turn off mapping for this entity prop only for this one sproc?
Problem 1 is due to the proc not having the columns to populate the entity. You don't really need the proc if you have mapped the table, just select the field you want from it using linq
var result = MyEntities.EntityIMapped.First(r => r.id = uberParameter).Name;
Would give you the value from the Name column of the table for the given id. You don't need to use a stored proc for this.
Problem 2 sounds like it is in the proc, I would think that distinct on an xml data column would give a lot of results, but I'm only guessing as I don't know your solution.
This is not a direct answer for your question but, hopefully it will point you in the right direction.

Resources