confused by oracle error msg : PL/SQL: ORA-25137: Data value out of range - json

An error(PL/SQL: ORA-25137: Data value out of range ) was reported when I executed the following code in Oracle 21c.
create table t(id int ,j json);
insert into t values(1,'{"key":"valus"}');
DECLARE
b varchar2(100);
BEGIN
select cast(j as varchar2(100)) into b from t where id=1;
DBMS_OUTPUT.PUT_LINE(b);
END;
The error message is
ERROR at line 4:
ORA-06550: line 4, column 15:
PL/SQL: ORA-25137: Data value out of range
ORA-06550: line 4, column 3:
PL/SQL: SQL Statement ignored
The oracle version I used is
Oracle Database 21c Enterprise Edition Release 21.0.0.0.0 - Production Version 21.3.0.0.0
I can't understand why this error was reported.
I think the cast target size I set is enough, but "ORA-25137: Data value out of range" was reported.
Can anyone explain why?

The data is stored in the table in binary format so you should use JSON_SERIALIZE function to convert JSON from any supported type into text. It is available since 19c:
Select t.id, json_serialize(t.j) From tbl t;
id j
---- -------------------
1 {"key":"valus"}
or, for previous versions use some of json functions like:
Select t.id, json_value(t.j, '$.key') as json_key From tbl t;
id json_key
---- -------------------
1 valus
There are more functions and options to get your data using sql with json datatype (json_query(), json_table(), ...)
You can find more about it -- https://oracle-base.com/articles/21c/json-data-type-21c

Related

Oracle 12c JSON Query Issue with Dot Notation and Double Quotes

I have a table "EvMetadata" with column "Metadata" that has a check constraint of "IS JSON". Note that the table and its columns are created with DOUBLE QUOTES by design.
Following SQL works where I'm not specifying any JSON work to be done by Oracle.
select
m."Metadata"
from "EvMetadata" m
As you can see below, the Metadata column simply displays its content which happens to be JSON data.
However, I get error if I were to issue a json query as follows.
select
m."Metadata"."FileName"
from "EvMetadata" m
I just added "FileName" using dot notation. As you can see above, "FileName" is a valid json field. So why the error?
Error is
ORA-00904: "M"."Metadata"."FileName": invalid identifier 00904. 00000 - "%s: invalid identifier" *Cause: *Action: Error at Line: 2 Column: 3
Could this be a bug with Oracle's JSON query support using the dot notation under a specific scenario where database objects are declared with double quotes? The reason I suspect that may be true is that the following equivalent query, not using the dot notation, works.
select
JSON_VALUE(m."Metadata", '$.FileName')
from "EvMetadata" m
You need to have an "IS JSON" check constraint on the column for dot notation to work:
Here's an excerpt from the documentation:
Each json_key must be a valid SQL identifier, and the column must have an is json check constraint, which ensures that it contains well-formed JSON data. If either of these rules is not respected then an error is raised at query compile time. (The check constraint must be present to avoid raising an error; however, it need not be active. If you deactivate the constraint then this error is not raised.)
Here's a test example I did to verify this is how it's working:
--create a table to put stuff in
create table foo (
json varchar2(4000)
);
--------------------------------
Table FOO created.
--insert test value
insert into foo(json) values('{"attr1":5,"attr2":"yes"}');
commit;
--------------------------------
1 row inserted.
Commit complete.
--try some selects
--no table alias, no constraint, borked
select json.attr1 from foo;
--------------------------------
Error starting at line : 12 in command -
select json.attr1 from foo
Error at Command Line : 12 Column : 8
Error report -
SQL Error: ORA-00904: "JSON"."ATTR1": invalid identifier
00904. 00000 - "%s: invalid identifier"
*Cause:
*Action:
--with table alias, no constraint, borked
select a.json.attr1 from foo a;
--------------------------------
Error starting at line : 15 in command -
select a.json.attr1 from foo a
Error at Command Line : 15 Column : 8
Error report -
SQL Error: ORA-00904: "A"."JSON"."ATTR1": invalid identifier
00904. 00000 - "%s: invalid identifier"
*Cause:
*Action:
--add our constraint
alter table foo add constraint json_isjson check (json is json);
--------------------------------
Table FOO altered.
--no table alias, with constraint, borked
select json.attr1 from foo;
--------------------------------
Error starting at line : 21 in command -
select json.attr1 from foo
Error at Command Line : 21 Column : 8
Error report -
SQL Error: ORA-00904: "JSON"."ATTR1": invalid identifier
00904. 00000 - "%s: invalid identifier"
*Cause:
*Action:
--table alias and constraint, works!
select a.json.attr1 from foo a;
--------------------------------
ATTR1
--------------------------------------------------------------------------------
5
In case anyone else gets this issue, its documented in Oracle Support under note 2192052.1
Basically, it's a bug whereby Dot Notation doesn't work on a column which is created with a NOT NULL constraint, i.e.
If you do:
CREATE TABLE foo.bar (id NUMBER NOT NULL, json_doc CLOB NOT NULL CHECK (json_doc IS JSON));
you'll get the error when you run:
SELECT a.json_doc.elementName FROM foo.bar a;
but if you do:
CREATE TABLE foo.bar (id NUMBER NOT NULL, json_doc CLOB CHECK (json_doc IS JSON));
ALTER TABLE bar MODIFY (json_doc NOT NULL);
the Dot notation will work.
You do not need quotes, this shall work:
select m.Metadata.FileName from EvMetadata m
Please refer to the example of official documentation:
SELECT po.po_document.PONumber FROM j_purchaseorder po;
SELECT json_value(po_document, '$.PONumber') FROM j_purchaseorder;

SQL Server could not convert data value

I am trying to import data from SQL Server to mysql using OPENQUERY with a linked server.
I have imported couple of tables but I am having an issue with a table that has a long varchar field.
everytime i run this query I get the following
Msg 7344, Level 16, State 1, Line 2
The OLE DB provider "MSDASQL" for linked server "Serv1" could not INSERT INTO table "[MSDASQL]" because of column "Notes". Could not convert the data value due to reasons other than sign mismatch or overflow.
the column Notes is of the type varchar(8000) in SQL servr and also varchar(8000) in MySQL.
What is the issue? why it is giving me this error? not I have tried to case Notes to varchar(8000) first but that did not work.
INSERT OPENQUERY (Serv1, 'SELECT
id,
i3_identity,
mid,
Notes,
Comments,
result_code,
Disposition,
completed_on,
calltype
FROM finaltesting.activities')
SELECT
CAST(ID AS int) AS id,
CAST(identity AS int) AS identity,
CAST(merchantAccount AS varchar(255)) AS mid,
Notes,
CAST(Comments AS varchar(8000)) AS Comments,
CAST(FinishCode AS varchar(255)) AS result_code,
CAST(Disposition AS varchar(255)) AS Disposition,
CAST(callDate AS datetime) AS completed_on,
CAST(CallType AS varchar(255)) AS calltype
FROM activities
Could not convert the data value due to reasons other than sign mismatch or overflow.
I was able to solve this problem by changes the column type in MySQL from varchar(8000) to Text. I am using MySQL 5.6.12. It is probably column type issue when converting form SQL Server to MySQL Server.
Thanks

Does JPA 2.0 support SQL Server table variables?

I am using JPA 2.0 and SQL Server 2008 and I have determined that JPA doesn't like my stored procedures when I use a table variable.
For example, this sproc works:
declare #t table
(
id int identity
, test varchar(50)
)
select 'blah' as test -- I'm ignoring the table variable above
However, when I try to insert something into the table variable #t with this code, it crashes:
declare #t table
(
id int identity
, test varchar(50)
)
insert into #t
select cast(getdate() as varchar(60))
select * from #t
I get the following error:
Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.0.2.v20100323-r6872): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: com.microsoft.sqlserver.jdbc.SQLServerException: The statement did not return a result set.
Error Code: 0
I would hate to have to rewrite my complex sprocs to not use table variables if I can help it.
Thanks for any suggestions.
Random thought: Try adding SET NOCOUNT ON.
Your code
insert into #t
select cast(getdate() as varchar(60))
select * from #t
...will return this
(1 row(s) affected)
id test
----------- --------------------------------------------------
1 Jun 14 2011 3:58PM
(1 row(s) affected)
There are actual three result "items" from SQL Server. The first has no assoicated result set.
... and a shameless plug of my question SET NOCOUNT ON usage where breaking ORMs and such is mentioned because of this

How to identify the culprit in "Error converting data type varchar to numeric"?

An insert statement with a large number of values returns 'Error converting data type varchar to numeric.'
How can I find which value actually triggers the error?
MS SQL Server 2008 is used.
you can use the function ISNUMERIC()
select * from table
where isnumeric(column) = 0
or
declare #v varchar(100)
select #v = 'abd'
select ISNUMERIC(#v)
Also take a look at this IsNumeric, IsInt, IsNumber post to help you further with these kind of problems

what is the out put?

Hi this is my code but when I run it in mysql it will show an error because of datatype but my friend checked it with sql server and it doesn't show error and also insert the value: 32769 .which of them is correct?
CREATE TABLE T1 (A INTEGER NOT NULL);
INSERT T1 VALUES (32768.5);
MySQL is (rightly in my view) getting upset because you have supplied a FLOAT value to a column that is expecting an INTEGER.
MS-SQL is performing an implicit conversion behind the scenes, but personally I think this is bad baheaviour - and MySQL's response (the error) is correct...
Your friend is correct. MySQL converts the number to an integer when inserting it. There is no error.
CREATE TABLE T1 (A INTEGER NOT NULL);
INSERT T1 VALUES (32768.5);
SELECT * FROM T1;
Result:
A
32769
Version information:
SELECT ##VERSION;
'5.1.41-community'