How to insert XML Content in db using SQL Module - xquery

I am a beginner in XQuery and
I could use some help on how to insert XML elements in my MySQL database. So far, it only inserts pieces of fragments of an xml file but I'd like to fetch the full fragments, including the elements along the content.
For instance, let's say I have :
let $element := "<exemple>hello world</exemple>"
let $currentDate := fn:format-dateTime(fn:current-dateTime(), "[Y0001]-[M01]-[D01] [H01]:[m01]:[s01]")
let $values := "('" || $element || "','" || $currentDate|| "','" || $currentDate || "')"
let $q := 'INSERT into table (element,created,updated) values ' || $values
let $conn := sql:connect("jdbc:mysql://xxxx:xxx#mysql:3306/database",map{'autocommit': true() ,'useUnicode':true(),'characterEncoding':'utf8'})
let $s := sql:execute($conn, $q)
let $conn := sql:close($conn)
-----------------------------------------------------
| id | element | created | updated |
-----------------------------------------------------
| x | hello world | xxxxx | xxxxx | <======== ? ( "<exemple>hello world</exemple>")
I actually need the full fragment. How to achieve that?
Thanks for your help.

Try serializing your element variable :
let $values := "('" || fn:serialize($element) || "','" || $currentDate|| "','" || $currentDate || "')"
Let me know how it goes

Related

Rename column if it has single quote

I need to rename column in my oracle database using pl/sql. For example you have table like this.
CREATE TABLE TEST(
id int,
"'test1" varchar(80),
"test2" varchar(80)
);
and you need to remove all quotes from it. I wrote anonymous block and there is the problem:
...
FOR column_rec IN (SELECT column_name FROM USER_TAB_COLUMNS WHERE TABLE_NAME=table_rec.TABLE_NAME) LOOP
new_column_name := column_rec.COLUMN_NAME;
new_column_name := REPLACE(new_column_name, chr(34), '');
new_column_name := REPLACE(new_column_name, chr(39), '');
...
EXECUTE IMMEDIATE
'ALTER TABLE '
|| table_rec.TABLE_NAME
|| ' RENAME COLUMN '
|| column_rec.COLUMN_NAME
|| ' TO '
|| new_column_name;
...
But if column_rec.COLUMN_NAME has just a single quote in it, this script will fail with exception ORA-01756, which means there is no closing quote. How can I avoid this exception?
Just use double quotes to wrap the columns' names even in your script; for example, this works:
alter table test rename column "'test1" to test1
Your script could be edited as:
EXECUTE IMMEDIATE
'ALTER TABLE '
|| table_rec.TABLE_NAME
|| ' RENAME COLUMN "' /* open the quote */
|| column_rec.COLUMN_NAME
|| '" TO ' /* and close */
|| new_column_name;
Also, notice that in this way all the renamed columns will be upper case; if this is what you need, well done, otherwise you have to wrap with double quotes even the new names:
...
|| '" TO "' /* and close, and reopen */
|| new_column_name || '"'; /* and close again */

PL/SQL - Send cyrillic characters using utl_smtp

In my case I store and retrieve Cyrillic characters into / from Oracle 11g db using NVARCHAR2 columns (see below a simple case)
create table cyrillic (texte varchar2(1000), ntexte nvarchar2(1000));
insert into cyrillic (texte, ntexte) values ('Hello World',N'Привет мир');
commit;
select * from cyrillic;
My aim now is to use the NVARCHAR2 column to prepare and send an email using UTL_SMTP.
I found several posts related to similar things but none is working (ie: Send mail in oracle with UTF-8 encoding in subject)
I always have a conversion issue in received email.
Is someone had the same need and found a solution ?
After several days of work and plenty of google search, I found the solution that works in my case.
Here the code:
create or replace procedure pr_send_mail_by_rawdata(p_subject nvarchar2, p_body nvarchar2) as
lv_server varchar2(255) := 'localhost';
lv_rcpt varchar2(255) := 'you#gmail.com';
lv_from varchar2(255) := 'me <me#gmail.com>';
lv_subject varchar2(4000):= 'cyrillic';
lv_conn utl_smtp.connection;
begin
lv_conn := utl_smtp.open_connection(lv_server);
UTL_SMTP.helo (lv_conn, lv_server);
UTL_SMTP.mail (lv_conn, lv_from);
UTL_SMTP.rcpt (lv_conn, lv_rcpt);
UTL_SMTP.open_data (lv_conn);
UTL_SMTP.WRITE_DATA(lv_conn, 'From' || ': ' || lv_from || UTL_TCP.CRLF);
UTL_SMTP.WRITE_DATA(lv_conn, 'To' || ': ' || lv_rcpt || UTL_TCP.CRLF);
lv_subject := '=?UTF8?Q?'||replace(utl_encode.TEXT_ENCODE(p_subject,'UTF8'),'='||chr(13) || chr(10)) || '?=';
UTL_SMTP.write_raw_data(lv_conn, utl_raw.cast_to_raw('Subject' || ': ' || lv_subject||utl_tcp.crlf ));
utl_smtp.write_data(lv_conn, 'MIME-version: 1.0' || utl_tcp.CRLF);
utl_smtp.write_data(lv_conn, 'Content-Type: text/html; charset=KOI8-R;'||utl_tcp.CRLF);
utl_smtp.write_data(lv_conn, 'Content-Transfer-Encoding: QUOTED-PRINTABLE'||utl_tcp.CRLF);
utl_smtp.write_data(lv_conn, utl_encode.TEXT_ENCODE(p_body,'CL8KOI8R'));
utl_smtp.write_data(lv_conn, utl_tcp.crlf);
utl_smtp.close_data(lv_conn);
utl_smtp.quit(lv_conn);
end;
Two things have been managed differently:
The subject:
Text is converted in utf8.
The body:
Text is converted in KOI8-R (charset : CL8KOI8R)

How to format pumped file in Oracle SQL Developer in any way?

My problem is that I unloaded a table from Oracle db into a text file with the following code:
PACKAGE BODY:
procedure d_datapump (tab_name in varchar2,
def_dir in varchar2 default 'MY_DIR',
xt_location in varchar2)
is
d_query varchar2(10000);
d_result varchar2(10000);
begin
d_query := ' create table ' || tab_name || '_xt
organization external
(
type oracle_datapump
default directory ' || def_dir || '
location ( ' || chr(39) || xt_location || chr(39) || ' )
)
as
select * from ' || tab_name;
d_result := '';
dbms_output.put_line (d_query);
execute immediate d_query;
dbms_output.put_line (d_result);
end d_datapump;
thereafter the call:
begin
david_ext_table.d_datapump(tab_name => 'D_TEST_TABLE',
xt_location => 'test_pac.txt');
end;
And it worked, but the result in my txt is something like this:
"?xml...many xml parameters .../ROWSET"
"XXXXXYYYYYZZZZZ§§§§§00000< "XXXXXYYYYYZZZZZ§§§§§00000<
"XXXXXYYYYYZZZZZ§§§§§00000< "XXXXXYYYYYZZZZZ§§§§§00000<
But I would like to see something like this (without xml block):
col1 | col2 | col3 | col4 | col5
-------------------------------------
XXXXX | YYYYY | ZZZZZ | §§§§§ | 00000
XXXXX | YYYYY | ZZZZZ | §§§§§ | 00000
XXXXX | YYYYY | ZZZZZ | §§§§§ | 00000
I have spent hours browsing for a solution and the only things I could find the tons of suggestion to use spooling and UTL_FILE instead of this way, because the datapump is only for creating a binary file, but It is obviously not binary but an ordinary text file.
Is there any way to format it?

PL/SQL procedure output stored in file and then email in Oracle 11g

I have a procedure where I am checking whether there are new codes. If there are then insert them into a table. And also save the new data into a csv or txt file and email them to me.
I can't get the logic for how to redirect the new data to file or just even put the data as simple text in the email. Thanks
create or replace
PROCEDURE new_codes_test( today_date IN VARCHAR2 DEFAULT NULL, v_proc_return OUT NUMBER) AS
sql_str VARCHAR2(4000);
.....
BEGIN
v_start_time := SYSDATE;
v_proc_return := 0;
....
INSERT INTO NEW_CODES_test
SELECT DISTINCT Sy_ID ,P_CODE, SYSDATE
FROM X.B
WHERE NOT EXISTS (SELECT DISTINCT Sy_ID, P_CODE
FROM X.C
WHERE today = today_date) ;
COMMIT;
--SELECT ___ into ___ from X.B;
sql_str := 'UTL_MAIL.send(sender => ''
,recipients => ''
,cc => ''
,subject => 'New codes'
,MESSAGE => '' )';
--EXECUTE IMMEDIATE sql_str;
p_proc_return := v_proc_return;
EXCEPTIONS
....
END;
To write to a file the UTL_FILE package will come in handy. To write an email you'll need to put the text to be sent into some sort of string before passing it to the MESSAGE argument of UTL_MAIL.SEND. You'll also need to be sure UTL_MAIL is installed and set up on your server; see this FAQ.
So something like the following may be useful:
CREATE OR REPLACE FUNCTION NEW_CODES_TEST(today_date IN VARCHAR2)
RETURN NUMBER
AS
strMessage VARCHAR2(32767);
nRows NUMBER := 0;
fHandle UTL_FILE.FILE_TYPE;
BEGIN
v_start_time := SYSDATE;
fHandle := UTL_FILE.FOPEN(someDirectory, someFilename, 'w');
FOR aRow IN (SELECT DISTINCT SY_ID ,P_CODE
FROM X.B
WHERE NOT EXISTS (SELECT DISTINCT Sy_ID, P_CODE
FROM X.C
WHERE today = today_date)
LOOP
INSERT INTO NEW_CODES_test
VALUES (aRow.SY_ID, aRow.P_CODE, SYSDATE);
UTL_FILE.PUT_LINE(fHandle, aRow.SY_ID || ', ' || aRow.P_CODE);
strMessage := strMessage || 'Added ' || aRow.SY_ID || ', ' ||
aRow.P_CODE || CHR(10);
nRows := nRows + 1;
END LOOP;
COMMIT;
UTL_FILE.FCLOSE(fHandle);
UTL_MAIL.SEND(sender => 'me#mycompany.com',
recipients => 'you#someplaceelse.net',
subject => 'New codes',
message => strMessage);
RETURN 0;
EXCEPTIONS
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('Error: ' || SQLERRM);
RETURN SQLCODE;
END NEW_CODES_TEST;
Share and enjoy.

SQLite problem selecting two columns as one

Basic table with empname and empdpt.
In a Sql Server table, I can do Select empname + ' ' + empdpt as expr1 no problem.
Can't do the same using Sqlite!!
When I try to combine two columns [with data], I get back a 0.
I've tried in sqliteman and sqliteadmin as well as Server Explorer in VS.
Try using the following:
SELECT ("test" || " " || "test2") AS expr1 ;
Update
If these are columns you can do something similar: SELECT (column1 || " " || column2) AS expr1 FROM your_table;
Select empname || " " || empdpt as expr1
The sqllite concat is the same as PostGreSQL ( || ) and not MYSQL or MSSQL 'CONCAT'
for those who are trying to use the (working) solution of #merkuru
SELECT (column1 || " " || column2) AS expr1 FROM your_table;
in eclipse or another editor:
you have to cancel the " with \
something like:
SELECT (column1 || \" \" || column2) AS expr1 FROM your_table;
that's works perfect
This worked for me in the where clause:
SELECT * FROM table_name WHERE(first_name || last_name) LIKE comparison_string;
For anyone like me. I had to add if statements to my query, do to some values equalling NULL as follows:
SELECT
(CASE WHEN table.column1 IS NULL THEN "" ELSE table.column1 END) || " " || (CASE WHEN table.column2 IS NULL THEN "" ELSE table.column2 END) as ColName
from table
note: I might mention my case uses SQLite with Python but should be the same for all SQLite cases

Resources