SnowSQL, procedure - error 904 when using variable in insert statement - sql

I'm working on snowflake procedure in snowsql and want to use variable as value in insert statement - something like that:
execute immediate $$
declare
select_statement string;
begin
select_statement := '''Some text''';
INSERT INTO SOME_TABLE(MESSAGE) values (select_statement);
exception
when statement_error then
return object_construct('Error type', 'STATEMENT_ERROR',
'SQLCODE', sqlcode,
'SQLERRM', sqlerrm,
'SQLSTATE', sqlstate);
when other then
return object_construct('Error type', 'Other error',
'SQLCODE', sqlcode,
'SQLERRM', sqlerrm,
'SQLSTATE', sqlstate);
end;
$$
;
{
"Error type": "STATEMENT_ERROR",
"SQLCODE": 904,
"SQLERRM": "SQL compilation error: error line 1 at position 102\ninvalid identifier 'SELECT_STATEMENT'",
"SQLSTATE": "42000"
}
I was trying to use single quote as well
select_statement := 'Some text';
and also without declaring it and using let
let select_statement := 'Some text';
Each time getting the same error...

please try this.
create or replace table SOME_TABLE(MESSAGE varchar2 );
select * from SOME_TABLE;
execute immediate $$
declare
select_statement string;
begin
select_statement := '''Some text''';
INSERT INTO SOME_TABLE(MESSAGE) values (:select_statement);
exception
when statement_error then
return object_construct('Error type', 'STATEMENT_ERROR',
'SQLCODE', sqlcode,
'SQLERRM', sqlerrm,
'SQLSTATE', sqlstate);
when other then
return object_construct('Error type', 'Other error',
'SQLCODE', sqlcode,
'SQLERRM', sqlerrm,
'SQLSTATE', sqlstate);
end;
$$;

This just needs some minor adjustments to the syntax. To use execute immediate as a string, create the string with one or more bind variables. Use the "using" clause to bind them in the execute immediate.
create or replace table some_table(message string);
execute immediate $$
declare
rs resultset;
select_statement string;
ins string default 'INSERT INTO SOME_TABLE(MESSAGE) values (?)';
begin
select_statement := 'Some text';
rs := (execute immediate :ins using (select_statement));
return table(rs);
exception
when statement_error then
return object_construct('Error type', 'STATEMENT_ERROR',
'SQLCODE', sqlcode,
'SQLERRM', sqlerrm,
'SQLSTATE', sqlstate);
when other then
return object_construct('Error type', 'Other error',
'SQLCODE', sqlcode,
'SQLERRM', sqlerrm,
'SQLSTATE', sqlstate);
end;
$$
;
The return of the table is optional, but helps with the return for programmatic access or human readability.
number of rows inserted
1

Related

ORACLE : renaming a key in a json field by oracle

I have a table in which in one of the columns there is a json data as below
COLUMN NAME : JSON_CODE
{
"DataElaborazione" : "20220718",
"DataMovimento" : "20220531",
"DataRiferimento" : "20220715",
}
I want to rename DataRiferimento to datarif
expected result
COLUMN NAME : JSON_CODE
{
"DataElaborazione" : "20220718",
"DataMovimento" : "20220531",
"datarif" : "20220715",
}
see image for structure
thank you
You can use JSON_TRANSFORM function:
select JSON_TRANSFORM('{ "DataElaborazione" : "20220718", "DataMovimento" : "20220531", "DataRiferimento" : "20220715" }',
RENAME '$.DataRiferimento' = 'datarif')
from dual
Or JSON_OBJECT_T:
declare
v_json JSON_OBJECT_T;
begin
v_json := JSON_OBJECT_T('{ "DataElaborazione" : "20220718", "DataMovimento" : "20220531", "DataRiferimento" : "20220715" }');
v_json.rename_key('DataRiferimento', 'datarif');
dbms_output.put_line(v_json.stringify);
end;
You can create function and use it in your query:
create or replace function renameJsonKey(p_json IN VARCHAR2,
p_old_key IN VARCHAR2,
p_new_key IN VARCHAR2) return VARCHAR2
RESULT_CACHE RELIES_ON (your_table)
is
v_json JSON_OBJECT_T;
begin
v_json := JSON_OBJECT_T(p_json);
v_json.rename_key(p_old_key, p_new_key);
return v_json.stringify;
end;
select renameJsonKey(col, 'DataRiferimento', 'datarif') from your table

plsql cannot use variables in sql select

I am getting very fed up of APEX in recent days, i am trying to run a interactive report within application express and cannot seem to use variables i declare within my sql queries. Below is the error, i also included the code that works. the get_longlat() function is tested and works it returns a SDO_GEOMETRY data type.
ORA-06550: line 7, column 12: PLS-00306: wrong number or types of
arguments in call to '||' ORA-06550: line 7, column 1: PL/SQL:
Statement ignored
DECLARE
l_query VARCHAR2(4096);
l_location SDO_GEOMETRY := get_longlat(v('P2_POSTCODE'));
BEGIN
l_query := '
SELECT
"VENUE_ID",
"VENUE_NAME",
"CITY",
"VENUE_NO",
"POSTCODE",
dbms_lob.getlength("THUMBNAIL") "THUMBNAIL",
"DESCRIPTION",
SDO_GEOM.SDO_DISTANCE(G_LOCATION, ' || l_location || ',0.005,''unit=mile'') "G_LOCATION"
FROM "GAMEVENUE"
WHERE (SDO_WITHIN_DISTANCE(G_LOCATION,' || l_location || ',''distance=250 unit=mile'') = ''TRUE'');';
RETURN l_query;
This works
l_query := '
SELECT
"VENUE_ID",
"VENUE_NAME",
"CITY",
"VENUE_NO",
"POSTCODE",
dbms_lob.getlength("THUMBNAIL") "THUMBNAIL",
"DESCRIPTION",
SDO_GEOM.SDO_DISTANCE(G_LOCATION, MDSYS.SDO_GEOMETRY(2001,4326,SDO_POINT_TYPE(-4.1530439,50.371089,NULL),NULL,NULL),0.005,''unit=mile'') "G_LOCATION"
FROM "GAMEVENUE"
WHERE (SDO_WITHIN_DISTANCE(G_LOCATION,SDO_GEOMETRY(2001,4326,SDO_POINT_TYPE(-4.1530439,50.371089,null),null,null),''distance=250 unit=mile'') = ''TRUE'')';
Because SDO_GEOMETRY is not of type char or number( implicitly considerable as char ), you can't use it in direct concetenation.
Try this instead :
l_query := '
SELECT
"VENUE_ID",
"VENUE_NAME",
"CITY",
"VENUE_NO",
"POSTCODE",
dbms_lob.getlength("THUMBNAIL") "THUMBNAIL",
"DESCRIPTION",
SDO_GEOM.SDO_DISTANCE(G_LOCATION, MDSYS.SDO_GEOMETRY('||l_sdo_gtype||','||l_sdo_srid||',MDSYS.SDO_POINT_TYPE('||l_longitude||','||l_latitude||',NULL),NULL,NULL),0.005,''unit=mile'') "G_LOCATION"
FROM "GAMEVENUE"
WHERE (SDO_WITHIN_DISTANCE(G_LOCATION,SDO_GEOMETRY('||l_sdo_gtype||','||l_sdo_srid||',SDO_POINT_TYPE('||l_longitude||','||l_latitude||',null),null,null),''distance=250 unit=mile'') = ''TRUE'')';
where l_sdo_gtype,l_sdo_srid, l_longitude, l_latitude are of type number;

I want to extract the tag name using sql from table with XML stored as clob. (ORACLE)

Sample XML as below:
<Root>
...
<XMLNSC>
...
<SOAP-ENV:Envelope>
...
<SOAP-ENV:Body>
<typesNS0:getABCD xmlns:typesNS0="http://xxx.xx/xxxxxx/xxxxxxxxx/x/" xmlns:xalan="http://xml.apache.org/xslt">
last tag typesNS0:getABCD want to select
select xmltype(a).extract('//typesNS0:getABCD','xmlns:typesNS0="http://xxx.xx/xxxxxx/xxxxxxxxx/x/"')
from (
select
'<Root xmlns:SOAP-ENV="http://a.b.org/">
<XMLNSC />
<SOAP-ENV:Envelope/>
<SOAP-ENV:Body/>
<typesNS0:getABCD xmlns:typesNS0="http://xxx.xx/xxxxxx/xxxxxxxxx/x/" xmlns:xalan="http://xml.apache.org/xslt">123</typesNS0:getABCD>
</Root>' a from dual
)
You may run below script if you want get exact tag value;
DECLARE
vs_Xml VARCHAR2(32000):= '<Root xmlns:SOAP-ENV="http://a.b.org/">
<XMLNSC />
<SOAP-ENV:Envelope/>
<SOAP-ENV:Body/>
<typesNS0:getABCD xmlns:typesNS0="http://xxx.xx/xxxxxx/xxxxxxxxx/x/" xmlns:xalan="http://xml.apache.org/xslt">123</typesNS0:getABCD>
</Root>';
vx_ParameterList XMLTYPE;
vx_Parameter XMLTYPE;
vn_ParameterIndex NUMBER;
vs_Key VARCHAR2(64);
vs_XPath VARCHAR2(255);
vs_Value VARCHAR2(10000);
BEGIN
vx_ParameterList := xmltype(vs_Xml);
vn_ParameterIndex := 1;
vs_XPath := '/Root';
WHILE vx_ParameterList.existsNode(vs_XPath || '[' || vn_ParameterIndex || ']') = 1 LOOP
vx_Parameter := vx_ParameterList.extract(vs_XPath || '[' || vn_ParameterIndex || ']');
vs_Value := vx_Parameter.extract('//typesNS0:getABCD/text()','xmlns:typesNS0="http://xxx.xx/xxxxxx/xxxxxxxxx/x/"').GetStringVal();
vn_ParameterIndex := vn_ParameterIndex + 1;
dbms_output.put_line(vs_Value);
END LOOP;
END;

ArrayIndexOutOfBoundsException when running Liquibase

I am using Spring and Liquibase to deploy the following SQL code:
BEGIN;
CREATE OR REPLACE FUNCTION public.get_clear_name_city(IN dirty TEXT, OUT clear TEXT) AS $$ SELECT trim(regexp_replace(regexp_replace(trim(dirty), '^(г |пгт |рп |кп |п |к |нп |п.ст |п ж/д ст |г. |пгт. |рп. |кп. |дп. |гп. |п. |к. |нп. |п.ст. |п. ж/д ст|п. ж/д ст.|п ж/д ст. |ж/д блокпост |ж/д будка |ж/д ветка |ж/д казарма |ж/д комбинат |ж/д платформа |ж/д площадка |ж/д путевой пост |ж/д остановочный пункт |ж/д рзд |ж/д ст |местечко |д |с |сл |ст |ст-ца |у |х |рзд |д. |с. |м |м. |сл. |ст. |у. |х. |рзд. |зимовье |город |гидрологический пост |поселок городского типа |рабочий поселок |рабочий посёлок |курортный поселок |дачный поселок |городской поселок |поселок |посёлок |кишлак |населенный пункт |поселок при станции (поселок станции) |поселок при железнодорожной станции |железнодорожный блокпост |железнодорожная будка |железнодорожная ветка |железнодорожная казарма |железнодорожный комбинат |железнодорожная платформа |железнодорожная площадка |железнодорожный путевой пост |железнодорожный остановочный пункт |железнодорожный разъезд |железнодорожная станция |местечко |межселенные территории |метеостанция |монтерский пункт |деревня |село |сельское поселение |городское поселение |слобода |станция |станица |улус |усадьба |хутор |разъезд |зимовье )?', '', 'i'), '( сельское поселение| городское поселение)$', '', 'i')); $$ LANGUAGE SQL;
CREATE OR REPLACE FUNCTION public.get_clear_name_state(IN dirty TEXT, OUT clear TEXT) AS $$ SELECT trim(regexp_replace(regexp_replace(regexp_replace(trim(dirty), '^(город |городской округ |г |г. |закрытое административно-территориальное образование город |муниципальное образование город |муниципальное образование |муниципальный район |муниципальный р-н |м.район |мун.район |м. район |мун. район |р |р. |р/н |р-н )?', '', 'i'), ' республики.*', '', 'i'), '( район| р| р.| р/н| р-н| сельское поселение| городское поселение| муниципальный район| м.район| мун.район| м. район| мун. район| город| городской округ| г| г.| закрытое административно-территориальное образование| муниципальное образование)$', '', 'i')); $$ LANGUAGE SQL;
DELETE FROM city;
DELETE FROM state;
CREATE TYPE oktmo_name AS (oktmo TEXT, name TEXT);
CREATE OR REPLACE FUNCTION city_set(parent_oktmo INTEGER)
RETURNS SETOF oktmo_name AS $$
BEGIN
RETURN QUERY EXECUTE
'WITH RECURSIVE cities_oktmo AS (
SELECT * FROM oktmo WHERE oktmo.parent_id = ' || parent_oktmo ||
'UNION ALL
SELECT oktmo.* FROM oktmo
JOIN cities_oktmo ON oktmo.parent_id = cities_oktmo.id
)
SELECT city.oktmo::TEXT, city.name::TEXT FROM cities_oktmo city
LEFT JOIN cities_oktmo child ON city.id = child.parent_id
WHERE child.oktmo ISNULL AND char_length(city.oktmo) = 11
ORDER BY city.name';
END; $$ LANGUAGE plpgsql;
DO $$
DECLARE
state_cursor CURSOR FOR
SELECT oktmo, name FROM oktmo
WHERE parent_id = (select m.value::BIGINT from "public"."messages" m WHERE m.key='branding.region.oktmo'); state_guid UUID;
BEGIN
FOR st IN state_cursor LOOP
state_guid := uuid_generate_v4();
INSERT INTO state(guid, oktmo, name, clear_name) VALUES(state_guid, st.oktmo, st.name, get_clear_name_state(st.name));
INSERT INTO city(oktmo, name, clear_name, state_guid)
SELECT oktmo, name, get_clear_name_city(name), state_guid
FROM city_set(st.oktmo::INT4);
END LOOP;
END $$;
DROP FUNCTION city_set(parent_oktmo INTEGER);
DROP TYPE oktmo_name;
COMMIT;
When I try to start up my application I get the following exception:
Caused by: liquibase.exception.MigrationFailedException: Migration failed for change set classpath:changelogs/db-changelog-4.x.xml::GEO-6154_1::kadzhaev:
Reason: java.lang.ArrayIndexOutOfBoundsException
I think it could happen because of $$ sign but how I can fix it?
Just add splitStatements="false" and stripComments="false" to the <sql> label.
<changeSet id="1" author="admin">
<sql splitStatements="false" stripComments="false" >
<![CDATA[
your SQL
]]>
</sql>
</changeSet>
I have the same issue and I have resolved using
<createProcedure dbms="postgresql"
encoding="utf8"
path="yourFunction.sql"
relativeToChangelogFile="true"
/>

how to upload any file from local machine to database server file system using SQL developer

Here is my Code:
I need to upload a file from the local machine to the file system
Also, i got an error when opening the file attached in the oracle application (ORA-01403: no data found
FRM-40735: WHEN-BUTTON-PRESSED trigger raised unhandled exception
ORA-01403.)
CREATE OR REPLACE DIRECTORY in_file_loc AS '/oracle/TEST';
CREATE TABLE test_files (p_id NUMBER,
pl_name VARCHAR2(100),
pl_pict BLOB);
DECLARE
x_blob BLOB;
fils BFILE := BFILENAME ('IN_FILE_LOC', 'aa.pdf');
blob_length INTEGER;
BEGIN
-- Obtain the size of the blob file
DBMS_LOB.fileopen (fils, DBMS_LOB.file_readonly);
blob_length := DBMS_LOB.getlength (fils);
DBMS_LOB.fileclose (fils);
-- Insert a new record into the table containing the
-- filename you have specified and a LOB LOCATOR.
-- Return the LOB LOCATOR and assign it to x_blob.
INSERT INTO test_files (p_id,pl_name,pl_pict)
VALUES (7, 'aa.pdf', EMPTY_BLOB ())
RETURNING pl_pict
INTO x_blob;
-- Load the file into the database as a BLOB
DBMS_LOB.OPEN (fils, DBMS_LOB.lob_readonly);
DBMS_LOB.OPEN (x_blob, DBMS_LOB.lob_readwrite);
DBMS_LOB.loadfromfile (x_blob, fils, blob_length);
-- Close handles to blob and file
DBMS_LOB.CLOSE (x_blob);
DBMS_LOB.CLOSE (fils);
COMMIT;
-- Confirm insert by querying the database
-- for LOB length information and output results
blob_length := 0;
SELECT DBMS_LOB.getlength (pl_pict)
INTO blob_length
FROM test_files
WHERE pl_name = 'aa.pdf';
DBMS_OUTPUT.put_line ('Successfully inserted BLOB ''' ||'aa.pdf' || ''' of size ' || blob_length || ' bytes.');
END;
DECLARE
TYPE result_set_type IS REF CURSOR;
l_name VARCHAR2 (100);
l_doc_size NUMBER;
l_result_set_curr result_set_type;
x_access_id NUMBER;
x_file_id NUMBER;
p_file_name VARCHAR2 (100) := 'aa.pdf';
PROCEDURE load_file_details (p_name IN VARCHAR2, result_set_curr OUT result_set_type)
AS
l_error VARCHAR2 (2000);
BEGIN
INSERT INTO fnd_lobs_document
(NAME, mime_type, doc_size, content_type, blob_content)
SELECT pl_name, 'application/pdf', DBMS_LOB.getlength (pl_pict), 'BINARY', '(BLOB)'
FROM test_files
WHERE pl_name = 'aa.pdf';
OPEN result_set_curr FOR
SELECT blob_content
FROM fnd_lobs_document
WHERE NAME = p_name;
EXCEPTION
WHEN OTHERS
THEN
NULL;
l_error := 'LOAD_FILE_DETAILS - OTHERS' || SUBSTR (SQLERRM, 2000);
DBMS_OUTPUT.put_line (l_error);
END load_file_details;
PROCEDURE upload_file (v_filename IN VARCHAR2, x_access_id OUT NUMBER, x_file_id OUT NUMBER)
AS
v_access_id NUMBER;
v_file_id NUMBER;
x_errbuf VARCHAR2 (200);
BEGIN
v_access_id := fnd_gfm.authorize (NULL);
x_access_id := v_access_id;
DBMS_OUTPUT.put_line ('Access id :' || v_access_id);
-- The function fnd_gfm.confirm_upload return the file id
v_file_id :=
fnd_gfm.confirm_upload (access_id => v_access_id
, file_name => v_filename
, program_name => 'TEST'
, program_tag => 'TEST'
, expiration_date => NULL
, LANGUAGE => 'US'
, wakeup => TRUE
);
x_file_id := v_file_id;
DBMS_OUTPUT.put_line ('File id :' || x_file_id);
EXCEPTION
WHEN OTHERS
THEN
x_errbuf := 'Procedure upload_file errored out with the following error : ' || SQLERRM;
DBMS_OUTPUT.put_line (x_errbuf);
END upload_file;
BEGIN
fnd_global.apps_initialize (0, 20634, 401);
load_file_details (p_name => p_file_name, result_set_curr => l_result_set_curr);
upload_file (v_filename => p_file_name, x_access_id => x_access_id, x_file_id => x_file_id);
COMMIT;
END;
DECLARE
TYPE result_set_type IS REF CURSOR;
l_name VARCHAR2 (100);
l_doc_size NUMBER;
l_result_set_curr result_set_type;
x_access_id NUMBER;
x_file_id NUMBER;
p_file_name VARCHAR2 (100) := 'aa.pdf';
PROCEDURE attach_file (p_access_id IN NUMBER, p_file_Id in number, p_filename IN VARCHAR2)
IS
BEGIN
fnd_webattch.add_attachment (seq_num => 900
,category_id => 1
,document_description => 'Test1'
,datatype_id => 5
,text => NULL
,file_name => p_filename
,url => NULL
,function_name => 'INVIDITM'
,entity_name => 'MTL_SYSTEM_ITEMS'
,pk1_value => 85 --organization_id
,pk2_value => 10 --Inventory_item_Id
,pk3_value => NULL
,pk4_value => NULL
,pk5_value => NULL
,media_id => p_file_id
,user_id => 0
,usage_type => 'O'
);
DBMS_OUTPUT.put_line ('File Attached!');
EXCEPTION
WHEN OTHERS
THEN
DBMS_OUTPUT.put_line ('error in loading the attachement');
END attach_file;
BEGIN
fnd_global.apps_initialize (0, 20634, 401);
attach_file (p_access_id => x_access_id, p_file_id=>x_file_id,p_filename => p_file_name);
COMMIT;
END;
I believe we are mixing context here. I assume Local machine here means the machine that you build the PL/SQL - only issue here is when you run it runs within the server context. So i would either FTP the file to the server or load your file content to an oracle table in a different way.