Pass Values to a query through fucntions argument in Perl - oracle

I have a perl code which queries the Oracle 11G database to pull the count of the 'values' from a table.
$sqlStatement="SELECT count(values) FROM Table WHERE values IN ('value1','value2','value3',.... 'valuen')"
How can I pass the values in query through a subroutine's argument?
For example:
$sqlStatement="SELECT count(values) FROM Table WHERE values IN ($values)
subroutine($values)

Wouldn't it make more sense to pass in the values using an array rather than a scalar?
count_values(#values);
Then the subroutine could start like this:
sub count_values {
my #values = #_;
my $sql = 'select count(values) from table where values in (';
$sql .= join ',', ('?') x #values;
$sql .= ')';
my $sth = $dbh->prepare($sql);
$sth->execute(#values);
my $count = ($sth->fetchrow_array)[0];
}

Related

German characters en-/decoding issue

I have a perl script. The simplified version looks like this:
my $sel = "SELECT DBMS_METADATA.GET_DDL($type, '$name', '$owner') FROM DUAL";
my $sth = $dbh->prepare( $sel ) or die "Can't prepare statement: $DBI::errstr";
my $rc = $sth->execute or die "Can't execute statement: $DBI::errstr";
my $code = $sth->fetchrow();
$sql = "INSERT INTO MY_TABLE (CODE) VALUES (?)";
$stmt = $dbh->prepare($sql);
$stmt->execute($code);
So, the script simpy get a CLOB text, save it in a $code variable and insert it to a table.
The command SELECT * FROM NLS_DATABASE_PARAMETERS WHERE PARAMETER = 'NLS_CHARACTERSET'; returns WE8MSWIN1252.
My problem is, that in the $code variable occur German characters. After executing the INSERT to DB the encoding is wrong. The geman special characters(umlauts) are displayed not correctly. guess_encoding($code); returns Encode::XS=SCALAR(0x...).
How can I decode and encode the $code variable in a proper way? How can I check what the guess_encoding returns? As already mentioned, the 'CODE' field is of type CLOB.

ORA-01795: maximum number of expressions in a list is 1000 error in perl script

I'm trying to run a query with NOT IN clause like:
SELECT * FROM table WHERE column NOT IN (?,?,...) (>1000 items) and I'm getting ORA-01795: maximum number of expressions in a list is 1000 error.
In my script I'm doing something like:
my $lparam = join ', ' => ('?') x #ids;
$lquery = "SELECT * FROM table WHERE column NOT IN ($lparam)";
$lcsr = $zdb->prepare($lquery);
$lcsr->execute( #ids );
I want to split the NOT IN clause to something like where (A not in (a,b,c) AND A not in (d,e,f)) ... How can we achieve this?
Here you go, adding triples and counting them.
my $count = 0;
$lquery = "SELECT * FROM table WHERE (A ";
while (#ids -$count > 3) {
$lquery .= "NOT in (?, ?, ?) AND A ";
$count += 3;
}
my $lparam = join ', ' => ('?') x (#ids - $count);
$lquery .= "NOT IN ($lparam))";
You can go with the IN list using a combination of the column as follows:
SELECT * FROM table WHERE (column,1) NOT IN ((?,1),(?,1),...) (>1000 items)
Here, 1 is used as the second column. And you can give more than 1000 values in the IN clause list. It is a workaround of skipping the limit.

Fetch all rows of a ORACLE SQL query using PERL Script

I need to fetch all rows from an oracle sql query and then loop through each rows using PERL.
Below is some sample data and table
create table t1 (col1 varchar2(30));
insert into t1 values ('row1');
insert into t1 values ('row2');
insert into t1 values ('row3');
insert into t1 values ('row4');
insert into t1 values ('row5');
commit;
i have written PERL script like below to fetch above table --
# connexion a la base
my $dbh = DBI->connect( 'dbi:Oracle:'.$dbname,
$dbusername,
$pass,
{ PrintError => 0,
RaiseError => 1
}
) || die "Erreur lors de la connexion: $DBI::errstr";
print ("Connexion à la base de données $dbname avec $dbusername OK \n");
$requete = "select col1 from t1";
$sth_sql = $dbh->prepare($requete);
$sth_sql->execute(#row);
#row=$sth_sql->fetchrow_array;
my $size = #row;
print $size;
#$first=#row[0];
#$sec=#row[1];
print $sec;
print $first;
foreach $script_name (#row) {
print "$script_name\n";
}
the above code is returning only one row and size of the array is showing only 1 element in it.
I need to fetch all fives rows and then loop through them one by one.
please suggest what i am missing here !!
I am using oracle database.
Thanks
EDIT :
I have made some changes and it is working fine now
$requete = "select col1 from t1";
$sth_sql = $dbh->prepare($requete);
$sth_sql->execute();
##row=$sth_sql->fetchrow_array;
$sth_sql->bind_columns(undef, \$script_name);
print $sec;
print $first;
while ($sth_sql->fetch()) {
$script_sql=$script_name.".sql";
print "$script_sql\n";
}
The ->fetchrow_array function is documented in DBI. There you'll see documented that you can either use it within a loop:
$sth = $dbh->prepare("SELECT foo, bar FROM table WHERE baz=?");
$sth->execute( $baz );
while ( #row = $sth->fetchrow_array ) {
print "#row\n";
}
to retrieve all rows sequentially, or that you can use the ->fetchall_arrayref method to retrieve the complete resultset in one go:
$sth = $dbh->prepare("SELECT foo, bar FROM table WHERE baz=?");
$sth->execute( $baz );
my $rows = $sth->fetchall_arrayref;
for my $row (#$rows) {
print "#row\n";
}

How to use like clause in code iginiter query() WITH BIND PARAMS?

How to use like clause in code iginiter query() WITH BIND PARAMS?
Eg:
When I use
$query = 'SELECT mycol FROM mytable WHERE name LIKE %?';
$name = 'foo';
$db->this->query($query,array($name));
//the clause generated
//SELECT mycol FROM mytable WHERE id LIKE '%'foo'%'
//I expected this
//SELECT mycol FROM mytable WHERE id LIKE '%foo'
I don't to put param values inside query and use like below:
$query = 'SELECT mycol FROM mytable WHERE name LIKE '%foo';
Also I can not use $this->db->like() function as my query consists of:
INSERT IGNORE
and
INSERT INTO table SELECT col FROM table2;
Please suggests?
Thanks,
just use CodeIgniter Query Builder
$name = 'foo';
$query = $this
->db
->select('mycol')
->like('name', $name)
->get('mytable');
$query = 'SELECT mycol FROM mytable WHERE name LIKE ?';
$name = '%foo';
$this->db->query($query,array($name));
codeigniter will replace ? with 'params' value.
if you write this
$query = 'SELECT mycol FROM mytable WHERE name LIKE %?';
$name = 'foo';
//$db->this->query($query,array($name)); //you wrote this line wrong.
//it should be like this
$this->db->query($query,array($name));
it will produce
SELECT mycol FROM mytable WHERE name LIKE %'foo' //inverse comma after % ,actually before and after foo.
So your right way will be
$query = 'SELECT mycol FROM mytable WHERE name LIKE ?';
$name = '%foo';
$this->db->query($query,array($name));
It will produce
SELECT mycol FROM mytable WHERE name LIKE '%foo'
NOTE
You wrote this which is wrong
$db->this->query($query,array($name));
Right way
$this->db->query($query,array($name));

CodeIgniter parameterize integer and string

$code = Array(1,2,3,4)
$sql = "SELECT * FROM Table1 WHERE Field1 IN (?)";
$query = $this->db->query($sql, array($code));
$this->db->last_query() will show
"SELECT * FROM Table1 WHERE Field1 IN ('1,2,3,4')"
How can I remove the single quote in the IN condition?
Even if the $code is array of strings, example
$code = Array('This one', 'Next code', 'And this')
the statement will be:
"SELECT * FROM Table1 WHERE Field1 IN ('This one, Next Code, And This')"
Am I missing something ?
TIA.
You can use this simple and alternate way
$this->db->where_in('Field1',$code);
$this->db->get('Table1');
From codeigniter active record manual
$this->db->where() accepts an optional third parameter. If you set it
to FALSE, CodeIgniter will not try to protect your field or table
names with backticks.
$this->db->where('MATCH (field) AGAINST ("value")', NULL, FALSE);
So, put a 3rd parameter on a where clause with FALSE
Then your query should be
$this->db->select('*')
->where('Field1 IN('.$code.'),NULL,FALSE)
->get('Table1');

Resources