Iam using this part of an SQL Satement to fetch Information from an N:N Relationship.
The Goal is to have an view with an column like: "STRING1,STRING2,STRING3". This works fine but i have sometimes more than 4000 Bytes in the Column.
(SELECT
(RTRIM(XMLAGG(xmlelement(X, TABLE1.STRING||',') order by TABLE1.STRING).extract('//text()'),','))
FROM
STRING_HAS_TABLE1
JOIN TABLE1 STRING_HAS_TABLE1.STRING_ID = TABLE1.ID
WHERE
STRING_HAS_TABLE1.USER_ID = X.ID) AS STRINGS,
Oracle throws "Buffer overflow". I think the problem is the columntype inside the view: VARCHAR2(4000).
ERROR: ORA 19011 - Character string buffer to small
Any ideas to handle this without changing the whole application logic?
This is a problem converting implicitly between data types. You can get around it by treating it as a CLOB before trimming, by adding a getClobVal() call:
SELECT RTRIM(XMLAGG(xmlelement(X, TABLE1.STRING||',')
order by TABLE1.STRING).extract('//text()').getClobVal(),',')
FROM ...
The RTRIM documentation shows the types it accepts, and since XMLTYPE isn't listed that means it has to be doing an implicit conversion, apparently to VARCHAR2. (The same applies to the other TRIM functions).
But it does accept CLOB, so doing an explicit conversion to CLOB means RTRIM doesn't do an implicit conversion to a type that's too small.
Related
I have a simple view that takes a varchar and converts it to a float.
Select CAST(TRIM(Measurement) AS float) as Measurement
from MyTable
where Type = 'Some Value'
Now the view sees the column as a float, however when i try to query my view with a where clasue of Measurement = 10, then I get the error:
Error converting data type varchar to float.
I know the string value will always be a number (I have checked many times). I also got this through multiple rounds of testing before this error popped up in prod. My guess is that there are other measurements in the table that are not part of my results, but are causing this error (those measurements may not have existing during the testing).
Is there a way to clean up the query so the results are always treated as a float?
Thanks
You clearly have bad values in the column. You can find them using a regular expression (in most databases) or a try_ function in SQL Server.
For instance:
Select Measurement
from MyTable
where Type = 'Some Value' AND try_convert(float, measurement) is null;
Or:
where type = 'Some Value' and
not measurement ~ '^-?[0-9]*[.]?[0-9]+$'
Th ~ is Postgres for a regular expression match. Other databases have similar functionality with different syntax.
I have a nvarchar column in one of my tables that I have imported from Access. I am trying to change to an int. To move to a new table.
The original query:
insert into members_exams_answer
select
ua.members_exams_id, ua.exams_questions_id,
ua.members_exams_answers_value, ua.members_exams_answers_timestamp
from
members_exams as me
full join
UserAnswers1 as ua on me.members_exams_username = ua.members_exams_id
full join
exams_questions as eq on eq.exams_questions_id = ua.exams_questions_id
This throws an error:
Conversion failed when converting the nvarchar value 'AAAR78509883' to data type int.
I have tired:
select convert (int, UserAnswers1.members_exams_id)
from UserAnswers1
and
select cast(members_exams_id as integer) int_members_exams_id
from UserAnswers1
and
select cast (members_exams_id as int)
from UserAnswers1
All result in the same error
Conversion failed when converting the nvarchar value 'AAAR78509883' to data type int.
Clearly you are trying to convert data that is alphanumeric to an int and that cannot be done.
Looking at your data why are you insisting on converting it to an int when it cannot be an int? Why not just process it as an nvarchar?
Your problem could be systemic where all data has a leading alpha characters that you need to strip out (and hopefully the same number of alpha characters)
In that case use a substring to strip off the alphas (this assumes the name number of alphabetic characters in each record). Or use a varchar or nvarchar field instead of an int. If the number of leading characters varies or if they can be leading or trailing or some other combination, it will much more complex to fix than we can probably describe on the Internet.
The other possibility is that you simply have some bad data. In which case identify the records which are not numeric and fix them or null the value out if they cannot be fixed. This happens frequently when you have stored the data in an incorrect datatype.
I want to select and visualize the content of a column with CLOB datatype (>100 bytes).
select UTL_RAW.CAST_TO_VARCHAR2(DBMS_LOB.SUBSTR(ds_cirurgia,1,4000))
from AVISO_CIRURGIA
where cd_paciente = 123456789;
But I get this error:
[SELECT - 0 row(s), 0.000 secs] [Error Code: 997, SQL State: 42000] ORA-00997: illegal use of LONG datatype
I used UTL_RAW.CAST_TO_VARCHAR2(DBMS_LOB.SUBSTR()) in another column and it works.
What is wrong in this case?
You can just leave it with the call to DBMS_LOB.SUBSTR: it returns a varchar2:
select DBMS_LOB.SUBSTR(ds_cirurgia,1,4000)
from AVISO_CIRURGIA
where cd_paciente = 123456789
However, keep in mind that Oracle SQL is only capable of having a varchar2 with 4000 bytes, not 4000 characters. Your call can fail if the string contains Unicode characters.
Your column type is LONG not CLOB. Simple look up it in USER_TAB_COLUMNS.
Here are some workaround how to resolve it. I'd recoment to change the type to CLOB with CTAS.
create table t1 as
select ...
to_lob(c) c /* convert to CLOB */
from t;
After that you can simple cast to VARCHAR such as
cast (substr(col_name,1,4000) as varchar2(4000))
UPDATE
of course you may also use DBMS_LOB.SUBSTR
DBMS_LOB.SUBSTR(col_name,4000,1)
but please note the signature of this function: 2nd parameter is length, 3rd offset (not vice versa as in substr).
SELECT logicalTime, traceValue, unitType, entName
FROM vwSimProjAgentTrace
WHERE valueType = 10
AND agentName ='AtisMesafesi'
AND ( entName = 'Hawk-1')
AND simName IN ('TipSenaryo1_0')
AND logicalTime IN (
SELECT logicalTime
FROM vwSimProjAgentTrace
WHERE valueType = 10 AND agentName ='AtisIrtifasi'
AND ( entName = 'Hawk-1')
AND simName IN ('TipSenaryo1_0')
AND CONVERT(FLOAT , traceValue) > 123
) ORDER BY simName, logicalTime
This is my sql command and table is a view table...
each time i put "convert(float...) part " i get
Msg 8114, Level 16, State 5, Line 1
Error converting data type nvarchar to float.
this error...
One (or more) of the rows has data in the traceValue field that cannot be converted to a float.
Make sure you've used the right combination of dots and commas to signal floating point values, as well as making sure you don't have pure invalid data (text for instance) in that field.
You can try this SQL to find the invalid rows, but there might be cases it won't handle:
SELECT * FROM vwSimProjAgentTrace WHERE NOT ISNUMERIC(traceValue)
You can find the documentation of ISNUMERIC here.
If you look in BoL (books online) at the convert command, you see that a nvarchar conversion to float is an implicit conversion. This means that only "float"-able values can be converted into a float. So, every numeric value (that is within the float range) can be converted. A non-numeric value can not be converted, which is quite logical.
Probably you have some non numeric values in your column. You might see them when you run your query without the convert. Look for something like comma vs dot. In a test scenario a comma instead of a dot gave me some problems.
For an example of isnumeric, look at this sqlfiddle
I am using in insert statement to convert BDE table (source) to a Firebird table (destination) using IB Datapump. So the INSERT statement is fed by source table values via parameters. One of the source field parameters is alphanum (SOURCECHAR10 char(10), holds mostly integers and needs to be converted to integer in the (integer type) destination column NEWINTFLD. If SOURCECHAR10 is not numeric, I want to assign 0 to NEWINTFLD.
I use IIF and SIMILAR to to test whether the string is numeric, and assign 0 if not numeric as follows:
INSERT INTO "DEST_TABLE" (......, "NEWINTFLD",.....)
VALUES(..., IIF( :"SOURCECHAR10" SIMILAR TO '[[:DIGIT:]]*', :"SOURCECHAR10", 0),..)
For every non numeric string however, I still get conversion errors (DSQL error code = -303).
I tested with only constants in the IIF result fields like SOURCECHAR10" SIMILAR TO '[[:DIGIT:]]*', 1, 0) and that works fine so somehow the :SOURCECHAR10 in the true result field of the IIF generates the error.
Any ideas how to get around this?
When your query is executed, the parser will notice that second use of :"SOURCECHAR10" is used in a place where an integer is expected. Therefor it will always convert the contents of :SOURCECHAR10 into an integer for that position, even though it is not used if the string is non-integer.
In reality Firebird does not use :"SOURCECHAR10" as parameters, but your connection library will convert it to two separate parameter placeholders ? and the type of the second placeholder will be INTEGER. So the conversion happens before the actual query is executed.
The solution is probably (I didn't test it, might contain syntax errors) to use something like (NOTE: see second example for correct solution):
CASE
WHEN :"SOURCECHAR10" SIMILAR TO '[[:DIGIT:]]*'
THEN CAST(:"SOURCECHAR10" AS INTEGER)
ELSE 0
END
This doesn't work as this is interpreted as a cast of the parameter itself, see CAST() item 'Casting input fields'
If this does not work, you could also attempt to add an explicit cast to VARCHAR around :"SOURCECHAR10" to make sure the parameter is correctly identified as being VARCHAR:
CASE
WHEN :"SOURCECHAR10" SIMILAR TO '[[:DIGIT:]]*'
THEN CAST(CAST(:"SOURCECHAR10" AS VARCHAR(10) AS INTEGER)
ELSE 0
END
Here the inner cast is applied to the parameter itself, the outer cast is applied when the CASE expression is evaluated to true