JDBC Error in insert with DB2 (works with Sql Server) - jdbc

I use in a Java Application JDBC to query the DBMS. The application works correctly with Sql Server but I get this error in DB2 during one insert:
com.ibm.db2.jcc.am.SqlDataException: DB2 SQL Error: SQLCODE=-302, SQLSTATE=22001, SQLERRMC=1, DRIVER=3.63.75
The insert is made using the ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE.
My query is a plain select of the table, then I declare my PreparedStatement, passing the parameters and afterwards with the ResultSet I do first the moveToInsertRow() and then the insertRow().
Do you know if there are any problems with this approach using DB2?
As I told you before the same code works correctly with Sql Server.

SQL Code -302 on DB2 means:
THE VALUE OF INPUT VARIABLE OR PARAMETER NUMBER position-number IS INVALID OR TOO LARGE FOR THE TARGET COLUMN OR THE TARGET VALUE
So it seems like you are trying to insert a value into a column which is too large or too short (e.g. Hello World into a varchar(5)). Probably the column has a different length in DB2 and sql-server or you are inserting different values.

Probably too late to add to this thread.. but someone else might find it useful
Got the same SQL Exception when trying to do a SELECT : didn't realize the property value in WHERE clause was exceeding the limit on the corresponding column
SELECT * FROM <schema>.<table_name> WHERE PropertyName = 'value';
value was a VARCHAR type but exceeded the Length limit
Detailed exception does say it clearly that data integrity was violated: org.springframework.dao.DataIntegrityViolationException
So a good idea would be to do a length check on the value(s) that are being set on the properties before firing any queries to the database.

Related

Oracle generated column aliases different on two DB's

We have a legacy application we cannot modify that connects to Oracle 11g and at some point runs a query and returns a result. The application however is using the "generated" column name from Oracle to read the result.
Consider the following query:
select nvl(1,0.0) from DUAL;
As this query does not specify an alias, the generated column name would be "nvl(1,0.0)"
However on another server the generated column name is "nvl(1,0)" (notice 0 and not 0.0) and the application fails.
Is there a configuration that can be changed for Oracle? I've searched for formatting and locale configurations and they are equal on both servers.
Any help would be appreciated
It turns out there's a parameter called cursor_sharing that was set to FORCE instead of EXACT
select nvl(1,0.0) from DUAL;
The query above returns the following depending on the value of the parameter:
FORCE=NVL(1,0)
EXACT=NVL(1,0.0)

VB.NET OLEDBDataReader - Null value in resultset (DATETIME)

I'm new to VB.NET programming, so pointing to examples is greatly appreciated.
I've got a OleDB connection to an Oracle 11g database. I'm reading a single row from a table and trying to populate a row object (mClockInOutInfo). The problem I'm running into is that there is a null DateTime (timestamp) column in the returned row.
Of course, I started with the mClockInOutInfo.RowDate = dr.GetDateTime(0) (assume the RowDate column is the first column in the query).
I quickly found out that nulls should be checked, so I added the = If(IsDBNull(dr.GetDateTime(0)), DBNull.value, dr.getDateTime(0)) to the code. (I now use the NullSafeString functions found around here somewhere. But there was nothing for DateTime types. I tried to make one, no success. So I'm still with the If(IsDbNull(...)) code for my datetime columns.
The problem I'm having is that I get the error: "Specified cast is not valid." when evaluating that statement. I've verified the column type with the .GetDataTypeName(0) method. It returns DBTYPE_DBTIMESTAMP. I've reviewed the schema information to verify that the column is actually the information I'm looking for. From what I can tell, the error is being generated while evaluating the IsDBNull(drRecent.GetDateTime(0)) portion of the if() statement. I've confirmed this by breaking the statement into a multi-line if statement:
if IsDBNull(dr.GetDateTime(0)) Then
...
Else
...
End If
I get the same cast error thrown by the if IsDBNull(...) line.
So, I went back to the SQL string and did a Coalesce on the column with the empty data in it. I received the same cast error. Finally, frustrated, I changed the sql query to use the TO_DATE function and fed in a date string with the appropriate format parameter. I STILL receive this same cast error.
The property in the mClockInOutInfo is defined as DateTime. There are other columns defined exactly the same way and those that have data in the table are not giving any errors.
Any ideas of what I should be doing when the database allows nulls in a DateTime (Timestamp) column? All ideas welcomed. Thank you in advance.

DB2 Table as view in oracle shows character field as varchar2(0 Char)

I have the following problem: We have a DB2 Table with a Character Field of the size 4000.
Somehow this field gets interpreted in oracle as varchar2(0 Char) when i view it via Oracle Gateway.
CREATE OR REPLACE FORCE VIEW DB2SCHEMA.TEST_TABLE
(
ID,
TEXT
)
AS
SELECT TRIM ("ID") AS ID,
NULL AS "TEXT
FROM XT.TEST_TABLE#DB2SCHEMA;
Has anybody ever expirienced this issue? For some reason Oracle will treat this field as long. I'm using Oracle 11g. What i want is to show it as normal text field (in DB2 it is a fixed length character field)
Thanks for some inputs and maybe somebody knows how to get this as a normal Varchar2(4000 Char).
DESC XT.TEST_TABLE#DB2SCHEMA;
ORA-00604: error occurred at recursive SQL level 1
ORA-28500: connection from ORACLE to a non-Oracle system returned this message:
[Oracle][ODBC DB2 Wire Protocol driver][UDB DB2 for OS/390 and z/OS]UNAVAILABLE RESOURCE CAUSED FAILED EXEC; 00D70024 TYPE 00000220. XT.DSNDBC.DSNDB06.DSNDLX04.I0001.A001 {HY000,NativeErr = -904}
ORA-02063: preceding 2 lines from QDBC
As before the select * from view did provide a 0 character field we have changed an Oracle Parameter
HS_KEEP_REMOTE_COLUMN_SIZE=LOCAL
This provides the correct result with select * from view. My believe is that this is the solution.
I've never used Oracle Gateway or DB2, but any view you create by selecting "null as some_col" is going to define that column as varchar2(0). You're not even referencing the column you're talking about from the DB2SCHEMA (you're selecting NULL, not the TEXT column.
You could try replacing this line:
NULL AS "TEXT
with:
TEXT AS TEXT
or possibly:
SUBSTR(TEXT,1,2000) || SUBSTR(TEXT,2001,4000) AS TEXT
Oracle's maximum size for CHAR columns is 2000, so I'm not sure if you can just select the column directly.
Edit: As per comments, the OP's issue was fixed via changing the Oracle parameter:
HS_KEEP_REMOTE_COLUMN_SIZE=LOCAL

INSERT SELECT not working

Using Informix 11.7, I'm trying to execute a INSERT SELECT query with jdbc positional parameters in the select statement like this :
INSERT INTO table1(id, code, label)
SELECT ?, ?, ? FROM table2
WHERE ...
Parameters are set like this :
stmt.setString(1, "auniqueid");
stmt.setString(2, "code");
stmt.setString(3, "coollabel");
I get the following error :
Exception in thread "main" java.sql.SQLException: A syntax error has occurred.
When positional parmeters "?" are placed elsewhere it works fine. I have not this problem using PostgreSQL. What's wrong with my query ? I use the Informix JDBC Driver v3.70 JC1.
Thanks for your help.
Are you expecting to get column names specified via the placeholders? If so, you're on a hiding to nothing; you cannot use placeholders for structural elements of a query such as column or table names. They can only ever replace values. If you want dynamic SQL to specify the columns, use dynamic SQL; create a string with the content:
INSERT INTO table1(id, code, label)
SELECT auniqueid, code, coollabel
FROM table2
WHERE ...
and work with that.
If those placeholders were going to be values, then you'd be inserting the same values over and over, once for each row returned by the query, and that normally isn't what you'd want; you'd simply insert one row with a VALUES clause, where placeholders are permitted:
INSERT INTO table1(id, code, label) VALUES(?, ?, ?);
That would work fine.
AFAIK, this behaviour conforms to the SQL standard. If it works differently in PostgreSQL, then PostgreSQL has provided an extension to the standard.
Warning: I have no experience with Informix, answer is based on general observations
When specifying parameters the database will need to know the type of each parameter. If a parameter occurs in the select-list, then there is no way for the database to infer the type of the parameter. Some database might be capable of delaying that decision until it actually receives the parameters, but most database will need to know this at parse time. This is probably the reason why you receive the error.
Some databases - I don't know if this applies to Informix - allow you to cast parameters. So for example:
SELECT CAST(? AS VARCHAR(20)), CAST(? AS VARCHAR(10)), CAST(? AS VARCHAR(5)) FROM ...
In that case the database will be able to infer the parameter types and be able to parse the query correctly.
With this I do assume you are not trying to specify columnnames for the select-list using parameters, as that is not possible.

ORA-01400 can't insert null value... but I am NOT inserting null value!

I am trying to insert data in an Oracle table by using ODP.NET from a C# application, but I am getting an ORA-01400 can't insert null value error for a column in which I am NOT inserting a null value.
This is the stripped down version of the parametrized SQL command I am trying to execute. It is wrapped in an OracleCommand and executed with an invokation of ExecuteNonQuery:
declare c int;
begin
select count(*) into c from "Entradas" where "Id" = :Id and nvl("AppId", 0) = nvl(:AppId, 0);
if c>0 then
update "Entradas" set
/*...a bunch of columns...*/,
"VisitaLaboral" = :VisitaLaboral,
/*...some more columns...*/
where "Id" = :Id and nvl("AppId",0) = nvl(:AppId, 0);
else
insert into "Entradas" (
/*... a bunch of columns...*/,
"VisitaLaboral",
/*...some more columns...*/
) values (
/*...a bunch of values...*/,
:VisitaLaboral,
/*...some more values...*/
);
end if;
end;
The row does not exist previously so it is the insert part of the command the one that is executed. Of course I have verified that all the column names and column value parameters are properly placed in the SQL text.
The problem is in the VisitaLaboral column. It is of type NUMBER(1,0), it does not accept NULLs, and I am trying to insert a value of 0. This is what Visual Studio displays about the associated OracleParameter immediately before the command execution:
However if I execute the command directly in Application Express (providing the values directly in the command text), it works fine and the row is inserted.
So, what is happening here? Is there a bug in the ODP.NET library, or am I doing something wrong?
Additional information:
Database is Oracle 10g Express Release 10.2.0.1.0
Oracle.DataAccess.dll version is 4.112.1.2
Using Visual Studio 2010, targeting .NET framework 4.0
Thank you in advance!
UPDATE:
Everything works fine if I use the (deprecated) System.Data.OracleClient classes instead of ODP.NET.
WTF, Oracle? No, really, WTF?
Your problem seems to be that you don't know what is actually happening in the database. The quickest solution will be to find out what happens and use that.
connect to the database
use dbms_session.set_sql_trace(true) to enable an sql trace
do your application action
disconnect from the database
find - or ask your dba - to send you the raw trace file
In the tracefile (a plain text file) find your code and see what happens when the error is raised.
It could be that a trigger fired ....
This is a DB level error message, you can be sure that the insert has null value. Is it possible to log out the sql statement generated by the ODP.NET?
Are you really really sure that you have the columns in the same order on both the insert clause and the values clause? Check your "bunch of columns" ...
Well I know nothing about ODP.net, but if there is a value in the parameter, should the precison, scale and size attributes all be zero (as they appear to be)?
We had the same problem. We solved the problem setting column property "IsNullable" to true.

Resources