Insert datetime into Oracle using perl DBI parameterized INSERT statement - oracle

I need to insert a datetime value into an Oracle database table using perl. The following code inserts the required value:
use strict;
use warnings;
use DBI ;
use DBD::Oracle ;
my $SRV1='server1';
my $DB1='database1';
my $Date_Str_To_Insert="TO_DATE('2003/05/03 21:02:44','yyyy/mm/dd hh24:mi:ss')";
my $db1 = DBI->connect("dbi:Oracle:$SRV1/$DB1", "user", "pword");
my $SQL1="insert into table1 (valdat) values ($Date_Str_To_Insert)";
my $SQL1_sth = $db1->prepare($SQL1);
$SQL1_sth->execute();
$SQL1_sth->finish();
$db1->disconnect if defined($db1) ;
However, if I replace
my $SQL1="insert into table1 (valdat) values ($Date_Str_To_Insert)";
by
my $SQL1="insert into table1 (valdat) values (?)";
and
$SQL1_sth->execute();
by
$SQL1_sth->execute($Date_Str_To_Insert);
Then I get the following error:
DBD ERROR: error possibly near <*> indicator at char 42 in 'insert into t_datatable (valdat) values (:<*>p1)') [for Statement "insert into t_datatable (valdat) values (?)" with ParamValues: :p1='TO_DATE('2021-08-04 11:03:05','yyyy-mm-dd hh24:mi:ss')'] at perltestprog.pl line 6977.
How can I define the variable $Date_Str_To_Insert so that it works using the question mark notation?

Try this one:
my $SQL1 = "insert into table1 (valdat) values (TO_DATE(?,'yyyy/mm/dd hh24:mi:ss'))";
my $SQL1_sth = $db1->prepare($SQL1);
$SQL1_sth->execute('2003/05/03 21:02:44');

Related

ERROR: File XXXX is sequential. This task requires reading observations in a random order, but the engine allows only sequential access

I am trying to update an oracle table.
I encounter this error when running the following data step:
data oracle.have(drop=_:);
modify oracle.have end=last;
if _n_=1 then do;
declare hash h1(dataset:'_update');
declare hiter hh1('h1');
_rc = h1.defineKey('id','tid','valid_to');
_rc = h1.defineData('valid_from');
_rc = h1.defineDone();
end;
if h1.find()=0 then do;
replace;
_rc = h1.remove();
end;
run;
ERROR: File ORACLE.HAVE.DATA is sequential.
This task requires reading observations in a random order, but the
engine allows only sequential access.
Is there any way to bypass this error ?
Apparently, modify statements only works with SAS data sets.
The workaround I use is the following:
proc sql;
update have t1
set valid_from = (select valid_from from _update t2
where t1.id = t2.id
and t1.tid = t2.tid
and t1.valid_to = t2.valid_to
and t2.dim="FROM")
where catx('#',id, tid, valid_to) in (select catx('#',id, tid, valid_to)
from _update t3
where t3.dim="FROM");
quit;

ORA-00936: missing expression using SELECT INTO local_variable

I am trying to assing a result to a local variable in stored procedure sql.
For example
Select c.parm_val from Cusomter.name c where c.id = '102';
The above query gives me a result like 36,1508,4399,4403,4405,4407,4409,4411,4419
I want to assign it to a local variable
So I created in stored procedure like below
DECLARE
values VARCHAR2(500 BYTE);
BEGIN
Select into values c.parm_val from Cusomter.name c where c.id = '102';
END
When I execute this I get different errors each time
Something like PL/SQL: ORA-00936: missing expression
I want to assign those result a variable. I don't know if I can use INSERT as it not a table.
Can someone help me how to assign it to a variable.
I'm not sure about the syntax you are using. The FROM clause requires a table name like Customer, not Customer.name, which seems to be a column.
Starting with 11g Release 2 you can use the LISTAGG function to concatenate a column from the result rows into a single string.
SELECT LISTAGG(c.name, ',') WITHIN GROUP (ORDER BY c.name) INTO "values"
FROM Customer c
WHERE c.id = '102';
If c.id has a numeric type, drop the quotes: WHERE c.id = 102.
According to your comment, you probably want something like
SELECT c.name INTO "values"
FROM Customer c
WHERE c.id = '102';
See: PL/SQL SELECT INTO
Also, VALUES is a reserved word in SQL. Therefore, either choose another name, or escape it as "values" (in the declaration as well).
INTO comes after the field list:
Select c.parm_val into values from Cusomter.name c where c.id = '102';

Reverse SQL like not working in Oracle 12c

I need to do a reverse like query in Oracle 12c. While it works fine with H2, it fails in Oracle12c.
Table:
CREATE TABLE t
("id" int, "code" varchar(100))
;
INSERT ALL
INTO t ("id", "code")
VALUES (1, 'london')
INTO t ("id", "code")
VALUES (2, 'amsterdam')
INTO t ("id", "code")
VALUES (3, 'Oslo')
INTO t ("id", "code")
VALUES (4, 'Brussels')
SELECT * FROM dual
;
Query:
select * from t where 'london south' like concat('%',code, '%');
It gives error: ORA-00909: invalid number of arguments
How should i query it get (1, london) as the result?
Do NOT use double quotes around lower case column names in your DDL unless you really want to force Oracle to store the column names in lower case, which also means you need to use double quotes in your query:
select * from t where 'london south' like '%'||"code"||'%' ;
got the value london as the single row of output.
Why use the concat function when using || is more flexible?
Here you are a simpler test case:
select concat('a', 'b', 'c')
from dual;
ORA-00909: invalid number of arguments
The CONCAT() function expects exactly two arguments. You'll have to nest several calls or use the || operator.
select *
from t
where 'london south' like '%' || code || '%';

Write an Oracle procedure

I must create an oracle procedure to display a list of persons (parlimentaries) with an index for tuples.
For now, I wrote this piece of code (I haven't implemented the index)
create or replace procedure parlamentarieslist as
begin
select
ssn,
name,
surname,
from
parlimentaries p,
mandate m
where
p.ssn = m.parlamentaries AND m.legislature= (select
max(legislature) "m"
from mandate);
end parlamentarieslist;
However, oracle give me these errors
Error(5,3): PL/SQL: SQL Statement ignored
Error(12,3): PL/SQL: ORA-00936: missing expression
Why?
As I mentioned before in the comment part, the problem is due to
the missing INTO clause
existing typo(comma) after surname column in the uppermost select list.
Mostly, Procedures are used to return one column or single row and in results of SELECT statements may be returned to the output parameters by INTO clause. But, If you want to return list of persons (multi-rows), the following style may be more suitable :
SQL> set serveroutput on;
SQL> create or replace procedure parlamentarieslist as
begin
for c in
(
select p.ssn, p.name, p.surname,
max(m.legislature) over (partition by p.ssn ) m
from parlimentaries p inner join mandate m
on ( p.ssn = m.parlamentaries )
order by m.legislature desc
)
loop
dbms_output.put_line(' SSN : '||c.ssn||' Name : '||c.name||' Surname : '||c.surname);
end loop;
end parlamentarieslist;
/
SQL> exec parlamentarieslist;
Where Use a SQL of explict ANSI JOIN style, instead of old-fashioned comma seperated JOIN style.

Hive query issue :parameters

I need to assign a 'select value' in a parameter and use it in hive code instead of assigning constant to a parameter.
In Hive, set a = 10; //but instead of this how can we assign dynamic values, as follows:
I Need: set a = select max(x) from y; //which assign maximum value of 'x' from table 'y' to 'a' parameter.
Ayesha
You should use select instead of set, when you are assigning values directly from queries.
SELECT #variable1 = column1, variable2 = column2
FROM table1
WHERE column1 = 'unique value'
or
INSERT OVERWRITE LOCAL DIRECTORY '<directory>' SELECT * FROM table_name;
There's no way to do this from within Hive, but you can kind of do it from outside Hive, like in a bash script:
a=`hive -S -e 'select max(x) from y'`
hive --hiveconf "a=$a" -e '[next query here]'

Resources