I have one function which basically consume XML as input and do the next step.
I'm passing XML from one statement but it is giving error
"The string literal is longer than 4000 characters"
Function
create or replace FUNCTION F_ADD_TEST(P_XML_DATA CLOB) RETURN NUMBER AS
xmlContent xmlType;
RESP_XML XMLTYPE;
o xmlType;
c xmlType;
BEGIN
--xmlContent := xmlType(xmlData);
raise_application_error('-20003',P_XML_DATA);
-- Further steps
RETURN 1;
END F_ADD_TEST;
Statement
Select F_ADD_TEST('<?xml version="1.0" encoding="UTF-8"?>
<SyncReceiveDelivery xmlns:ln="http://schema.infor.com/InforOAGIS/2">
<DataArea>
<ReceiveDelivery>
<ReceiveDeliveryHeader>
<DocumentID>
<ID>100_ZHA005270</ID>
</DocumentID>
<WarehouseLocation>
<ID>W_ZHF12S</ID>
</WarehouseLocation>
</ReceiveDeliveryHeader>
<ReceiveDeliveryItem>
<LineNumber>10</LineNumber>
<ItemID>
<ID>24101600PA02435</ID>
<RevisionID>S000</RevisionID>
</ItemID>
<ReceivedQuantity>1</ReceivedQuantity>
<ServiceOrder>KRH000033</ServiceOrder>
</ReceiveDeliveryItem>
<ReceiveDeliveryItem>
<LineNumber>20</LineNumber>
<ItemID>
<ID>24101600PA04407</ID>
<RevisionID>S000</RevisionID>
</ItemID>
<ReceivedQuantity>4</ReceivedQuantity>
<ServiceOrder>KRH000033</ServiceOrder>
</ReceiveDeliveryItem>
</ReceiveDelivery>
</DataArea>
</SyncReceiveDelivery>') from dual;
If the XML content is huge I'm getting error
"The string literal is longer than 4000 characters"
I have changed datatype from Varchar to clob but still the same. Please help me on this.
In SQL, 'a value' is a text literal and the documentation states:
Text literals have properties of both the CHAR and VARCHAR2 datatypes:
Within expressions and conditions, Oracle treats text literals as though they have the datatype CHAR by comparing them using blank-padded comparison semantics.
A text literal can have a maximum length of 4000 bytes.
So your code is:
SELECT SOME_FUNCTION( 'A text literal which cannot be more than 4000 bytes' ) FROM DUAL
If you want to have more than 4000 bytes in a String in SQL then you cannot use a text literal and will have to pass in a CLOB via a bind parameter (either using PL/SQL or another language/middleware) or something like modifying your code to take a file name and load the XML from a file.
SELECT F_ADD_TEST( :bindparameter ) FROM DUAL;
Related
enter image description here
select from list by index ${locator_var} ${inp_msge_type}
--getting error as expected string, int found
select from list by index ${locator_var} 7
-----not getting any error
${inp_msge_type}----contains 7 from DB query the result is stored in this variable, to avoid hard coding we need to do this
Is there any way to write
Do not add links to screenshots of code, or error messages, and format the code pieces accordingly - use the ` (tick) symbol to surround them.
The rant now behind us, your issue is that the keyword Select From List By Index expects the type of the index argument to be a string.
When you called it
Select From List By Index ${locator_var} 7
, that "7" is actually a string (though it looks like a number), because this is what the framework defaults to on any typed text. And so it works.
When you get the value from the DB, it is of the type that the DB stores it with; and probably the table schema says it is int. So now you pass an int to the keyword - and it fails.
The fix is simple - just cast (convert) the variable to a string type:
${inp_msge_type}= Convert To String ${inp_msge_type}
, and now you can call the keyword as you did before.
I have a CSV file with some integer column, now it 's saved as "" (empty string).
I want to COPY them to a table as NULL value.
With JAVA code, I have try these:
String sql = "COPY " + tableName + " FROM STDIN (FORMAT csv,DELIMITER ',', HEADER true)";
String sql = "COPY " + tableName + " FROM STDIN (FORMAT csv,DELIMITER ',', NULL '' HEADER true)";
I get: PSQLException: ERROR: invalid input syntax for type numeric: ""
String sql = "COPY " + tableName + " FROM STDIN (FORMAT csv,DELIMITER ',', NULL '\"\"' HEADER true)";
I get: PSQLException: ERROR: CSV quote character must not appear in the NULL specification
Any one has done this before ?
I assume you are aware that numeric data types have no concept of "empty string" ('') . It's either a number or NULL (or 'NaN' for numeric - but not for integer et al.)
Looks like you exported from a string data type like text and had some actual empty string in there - which are now represented as "" - " being the default QUOTE character in CSV format.
NULL would be represented by nothing, not even quotes. The manual:
NULL
Specifies the string that represents a null value. The default is \N
(backslash-N) in text format, and an unquoted empty string in CSV format.
You cannot define "" to generally represent NULL since that already represents an empty string. Would be ambiguous.
To fix, I see two options:
Edit the CSV file / stream before feeding to COPY and replace "" with nothing. Might be tricky if you have actual empty string in there as well - or "" escaping literal " inside strings.
(What I would do.) Import to an auxiliary temporary table with identical structure except for the integer column converted to text. Then INSERT (or UPSERT?) to the target table from there, converting the integer value properly on the fly:
-- empty temp table with identical structure
CREATE TEMP TABLE tbl_tmp AS TABLE tbl LIMIT 0;
-- ... except for the int / text column
ALTER TABLE tbl_tmp ALTER col_int TYPE text;
COPY tbl_tmp ...;
INSERT INTO tbl -- identical number and names of columns guaranteed
SELECT col1, col2, NULLIF(col_int, '')::int -- list all columns in order here
FROM tbl_tmp;
Temporary tables are dropped at the end of the session automatically. If you run this multiple times in the same session, either just truncate the existing temp table or drop it after each transaction.
Related:
How to update selected rows with values from a CSV file in Postgres?
Rails Migrations: tried to change the type of column from string to integer
postgresql thread safety for temporary tables
Since Postgres 9.4 you now have the ability to use FORCE_NULL. This causes the empty string to be converted into a NULL. Very handy, especially with CSV files (actually this is only allowed when using CSV format).
The syntax is as follow:
COPY table FROM '/path/to/file.csv'
WITH (FORMAT CSV, DELIMITER ';', FORCE_NULL (columnname));
Further details are explained in the documentation: https://www.postgresql.org/docs/current/sql-copy.html
If we want to replace all blank and empty rows with null then you just have to add emptyasnull blanksasnull in copy command
syntax :
copy Table_name (columns_list)
from 's3://{bucket}/{s3_bucket_directory_name + manifest_filename}'
iam_role '{REDSHIFT_COPY_COMMAND_ROLE}' emptyasnull blanksasnull
manifest DELIMITER ',' IGNOREHEADER 1 compupdate off csv gzip;
Note: It will apply for all the records which contains empty/blank values
I have a string to modify as per the requirements.
For example:
The given string is:
str1 varchar = '123,456,789';
I want to show the string as:
'456,789'
Note: The first part (delimited) with comma, I want to remove from string and show the rest of string.
In SQL Server I used STUFF() function.
SELECT STUFF('123,456,789',1,4,'');
Result:
456,789
Question: Is there any string function in PostgreSQL 9.3 version to do the same job?
you can use regular expressions:
select substring('123,456,789' from ',(.*)$');
The comma matches the first comma found in the string. The part inside the brackets (.*) is returned from the function. The symbol $ means the end of the string.
A alternative solution without regular expressions:
select str, substring(str from position(',' in str)+1 for length(str)) from
(select '123,456,789'::text as str) as foo;
You could first turn the string to array and return second and third cell:
select array_to_string((regexp_split_to_array('123,456,789', ','))[2:3], ',')
Or you could use substring-function with regular expressions (pattern matching):
SELECT substring('123,456,789' from '[0-9]+,([0-9]+,[0-9]+)')
[0-9]+ means one or more digits
parentheses tell to return that part from the string
Both solutions work on your specific string.
Your The SQL Server example indicates you just want to remove the first 4 characters, which makes the rest of your question seem misleading because it completely ignores what's in the string. Only the positions matters.
Be that as it may, the simple and cheap way to cut off leading characters is with right():
SELECT right('123,456,789', -4);
SQL Fiddle.
I am trying to convert a string in Oracle into a modified string that is compatible with a specific API.
I would like to leave all alphanumeric characters intact, replace all spaces with the + character, and replace all special characters with % plus their hex code.
For example,
Project 1: Nuts & Bolts
should become
Project+1%3A+Nuts+%26+Bolts
Is there any way to do this using only SQL?
I don't think you can get there with plain SQL without nested replace calls. You can get your sample value with the utl_url.escape() function, but because you have to pass it a second parameter and that is a boolean, you have to do it in an PL/SQL block:
set define off
begin
dbms_output.put_line(replace(utl_url.escape('Project 1: Nuts & Bolts', true),
'%20', '+'));
end;
/
Project+1%3A+Nuts+%26+Bolts
The url_utl.escape function converts the spaces to %20:
Project%201%3A%20Nuts%20%26%20Bolts
... and the single replace call converts those to +.
As Ed Gibbs said, you can make that a function so you can at least call it from plain SQL:
create or replace function my_escape(str in varchar2) return varchar2 is
begin
return replace(utl_url.escape(str, true), '%20', '+');
end;
/
set define off
select my_escape('Project 1: Nuts & Bolts') from dual;
MY_ESCAPE('PROJECT1:NUTS&BOLTS')
--------------------------------
Project+1%3A+Nuts+%26+Bolts
You probably need to check the legal and reserved character lists to see if there's anything else that needs special handling.
(I've used set define off to stop my client treating the ampersand as a substitution variable; your client or application might not need that, e.g. if calling over JDBC).
apex_util.url_encode should work.
I have to insert the string "johnmelling" value into a table which has the column as
[USERPASS] varbinary NOT NULL.
Please could any one suggest me, what would be the best conversion to insert "johnmelling"?
I tried to to insert as below,
Insert into table(column1)
Values(CONVERT(varbinary(1), 'johnmelling'))
Then I got the error
Line 1: String or binary data would be truncated.
Thank You,
You are converting to varbinary(1) so your target datatype is varbinary but the integer you have specified in parentheses is 1 which means your datatype will only have a length of 1; you are receiving that error because the length you have allocated to that datatype is too small. The literal, 'johnmelling' is 11 characters but you are trying to store it in a datatype that has a length of 1.
Simply change the integer in parentheses to 11, 50, 255, max or whatever you think is an appropriate length and you won't get that error.