Oracle DBD Error from Perl script - sql

I am trying to run perl script but i get an oracle error.
DBD::Oracle::db prepare failed: ORA-01756: quoted string not properly terminated (DBD ERROR: OCIStmtPrepare)
But this SQL QUERY perfectly works fine in TOAD
MY perl connection details:
my $dbh = DBI->connect($dsn, $dbuser, $dbpass, { RaiseError => 1, AutoCommit => 0 });
my $sth=$dbh->prepare($SQL);
$sth->execute or die "EXEC ERROR $sth->errstr";
sql query:
SELECT name FROM employee WHERE
event IN ('IPO', 'RIGHTS')
AND (NOT market_code = 'ID' OR NOT event = 'RIGHTS')
AND NOT market_code = 'IN'
AND NOT market_code = 'NZ'
AND name NOT LIKE '%stat%'
AND NOT REGEXP_LIKE (name, 'S.K(Q|S)$')
AND name NOT LIKE '.%'
AND name NOT LIKE '%ol.SI'
AND name NOT LIKE '%bi.SI'

Perl will interpolate double-quoted string literals, like
my $SQL = "REGEXP_LIKE (name, 'S.K(Q|S)$')";
In here, your "variable" $' will be replaced with its value.
If you don't want that, use a non-interpolating version:
my $SQL = q{REGEXP_LIKE (name, 'S.K(Q|S)$')};
Single-quoted strings would also do, but since you have single quotes inside, the q{} is convenient. You can choose any terminator you want (such as q[]) and you can make it interpolate, too, with qq{}.

Related

Perl concatenation for SQL query

I'm trying to transfer the content of a CSV file into a table in PostgreSQL using Perl.
I'm able to update my table successfully, but the terminal returns an error:
Use of uninitialized value in concatenation (.) or string
Syntax error near ","
INSERT INTO test VALUES (, '', '', '', '',, )
Here is the code where it fails :
for (my $i=0 ; $i<=50; $i++){
$dbh ->do("INSERT INTO test VALUES ('$LastName[$i]', '$Street[$i]', $Balance_account[$i])") ;
If more information is needed just ask them.
Sorry for the bad English.
--
Thomas
Use placeholders,
for (my $i=0 ; $i<=50; $i++){
$dbh->do("INSERT INTO test VALUES (?,?,?)",
undef,
$LastName[$i], $Street[$i], $Balance_account[$i]
);
}
Ideally, you should prepare the query and execute for each set of values, something like this:
my $sth = $dbh->prepare('INSERT INTO test VALUES (?,?,?)');
for (my $i=0 ; $i<=50; $i++){
$sth->execute($LastName[$i], $Street[$i], $Balance_account[$i]);
}
My guess is that your error is being caused by not specifying the column names in your insert, while simultaneously having the wrong number/types of columns. I would expect the following Perl code to not error out:
for (my $i=0 ; $i<=50; $i++){
$dbh -> do("INSERT INTO test (lastname, street, balance) VALUES ('$LastName[$i]', '$Street[$i]', $Balance_account[$i])");
Here is what a working query might look like:
INSERT INTO test (lastname, street, balance)
VALUES
('Skeet', '100 Thatcher Street', 100.50);
It is generally considered bad practice to not include column names while doing an insert, because even if you get it right, it could easily break later on.

Ruby PG conn.exec_params SQL structure

I'm getting an error on a simple statement through PG:
require 'pg'
conn = PG.connect( dbname: 'myDB' )
#res = conn.exec_params( 'SELECT count(id) FROM users WHERE username = $1 AND status = "active"', ['johnny5'] )
The error:
/Users/rich/app.rb:14:in `exec_params': ERROR: column "active" does not exist (PG::UndefinedColumn)
LINE 1: ...unt(id) FROM users WHERE username = $1 AND status = "active"
^
"active" is a field value, not a column.
My question: I have fixed this by entering the value "active" as another placeholder. Are quoted values in the SQL not permitted? I assumed that quoted aspects of the SQL would have been fine.
String literals in SQL use sigle quotes, double quotes are for identifiers (such as table and column names). So, when you mention "active", the database complains that there is no such column.
The solution is to use a placeholder:
#res = conn.exec_params(
%q{SELECT count(id) FROM users WHERE username = $1 AND status = $2},
['johnny5', 'active']
)
or use single quotes inside the SQL:
#res = conn.exec_params(
%q{SELECT count(id) FROM users WHERE username = $1 AND status = 'active'},
['johnny5']
)
Switching from '...' to %q{...} for your SQL string literal makes the internal quoting problems a bit easier to deal with.

Multiple parameter values

I have a problem with BIRT when I try to pass multiple values from report parameter.
I'm using BIRT 2.6.2 and eclipse.
I'm trying to put multiple values from cascading parameter group last parameter "JDSuser". The parameter is allowed to have multiple values and I'm using list box.
In order to be able to do that I'm writing my sql query with where-in statement where I replace text with javascript. Otherwise BIRT sql can't get multiple values from report parameter.
My sql query is
select jamacomment.createdDate, jamacomment.scopeId,
jamacomment.commentText, jamacomment.documentId,
jamacomment.highlightQuote, jamacomment.organizationId,
jamacomment.userId,
organization.id, organization.name,
userbase.id, userbase.firstName, userbase.lastName,
userbase.organization, userbase.userName,
document.id, document.name, document.description,
user_role.userId, user_role.roleId,
role.id, role.name
from jamacomment jamacomment left join
userbase on userbase.id=jamacomment.userId
left join organization on
organization.id=jamacomment.organizationId
left join document on
document.id=jamacomment.documentId
left join user_role on
user_role.userId=userbase.id
right join role on
role.id=user_role.roleId
where jamacomment.scopeId=11
and role.name in ( 'sample grupa' )
and userbase.userName in ( 'sample' )
and my javascript code for that dataset on beforeOpen state is:
if( params["JDSuser"].value[0] != "(All Users)" ){
this.queryText=this.queryText.replaceAll('sample grupa', params["JDSgroup"]);
var users = params["JDSuser"];
//var userquery = "'";
var userquery = userquery + users.join("', '");
//userquery = userquery + "'";
this.queryText=this.queryText.replaceAll('sample', userquery);
}
I tryed many different quote variations, with this one I get no error messages, but if I choose 1 value, I get no data from database, but if I choose at least 2 values, I get the last chosen value data.
If I uncomment one of those additional quote script lines, then I get syntax error like this:
The following items have errors:
Table (id = 597):
+ An exception occurred during processing. Please see the following message for details: Failed to prepare the query execution for the
data set: Organization Cannot get the result set metadata.
org.eclipse.birt.report.data.oda.jdbc.JDBCException: SQL statement does not return a ResultSet object. SQL error #1:You have an error in
your SQL syntax; check the manual that corresponds to your MySQL
server version for the right syntax to use near 'rudolfs.sviklis',
'sample' )' at line 25 ;
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to
your MySQL server version for the right syntax to use near
'rudolfs.sviklis', 'sample' )' at line 25
Also, I should tell you that i'm doing this by looking from working example. Everything is the same, the previous code resulted to the same syntax error, I changed it to this script which does the same.
The example is available here:
http://developer.actuate.com/community/forum/index.php?/files/file/593-default-value-all-with-multi-select-parsmeter/
If someone could give me at least a clue to what I should do that would be great.
You should always use the value property of a parameter, i.e.:
var users = params["JDSuser"].value;
It is not necessary to surround "userquery" with quotes because these quotes are already put in the SQL query arround 'sample'. Furthermore there is a mistake because userquery is not yet defined at line:
var userquery = userquery + users.join("', '");
This might introduce a string such "null" in your query. Therefore remove all references to userquery variable, just use this expression at the end:
this.queryText=this.queryText.replaceAll('sample', users.join("','"));
Notice i removed the blank space in the join expression. Finally once it works finely, you probably need to make your report input more robust by testing if the value is null:
if( params["JDSuser"].value!=null && params["JDSuser"].value[0] != "(All Users)" ){
//Do stuff...
}

[ODBC Microsoft Access Driver]COUNT field incorrect

$q = 'INSERT INTO MyTable(proddesc, qnty, PriceH, PriceA, PriceL) VALUES(?,?,?,?,?)';
$sth = odbc_prepare($dbConn, $q);
$success = odbc_execute($sth, array(my 5 variables that are not null));
It gives me the above error - [ODBC Microsoft Access Driver] COUNT field incorrect. I know that the query is correct because I ran it in Access and it was fine. I think I may be using the prepare/execute statements incorrectly.
I also encountered this now and the solution I did to fix it is to quote the variables properly.
Try printing your $q and you will see if it needs to be quoted.
You can try these too:
INSERT INTO TABLE -- quote db and table names using (`) "grave accent" character
VALUES( 'Fed''s' ) -- quote the apostrophes

Active record query failed - Escape quote from query

Background
Framework: Codeignighter/PyroCMS
I have a DB that stores a list of products, I have a duplicate function in my application that first looks for the common product name so it can add a 'suffix' value to the duplicated product.
Code in my Products model class
$product = $this->get($id);
$count = $this->db->like('name', $product->name)->get('products')->num_rows();
$new_product->name = $product->name . ' - ' . $count;
On the second line the application fails only when the $product->name contains quotes.
I was with the understanding that Codeignighter escaped all strings so I dont know why I get this error.
So I tried to use MySQL escape string function but that didn't help either.
The Error Message
A Database Error Occurred
Error Number: 1064
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 's Book%'' at line 3
SELECT * FROM `products` WHERE `name` LIKE '%Harry\\'s Book%'
var_dump
Below is the output of doing a var_dump on product->name before and after the line in question;
string 'Harry's Book' (length=12)
A Database Error Occurred
Error Number: 1064
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 's Book%'' at line 3
SELECT * FROM `products` WHERE `name` LIKE '%Harry\\'s Book%'
Let's do some testing about this.
Here is what you are doing
$count = $this->db->like('name', $product->name)->get('products')->num_rows();
And i suspect $product->name contains this.
Harry's Book
As we know this is coming from the database table as you are using.
Where you are using the upper query mentioned it is wrapping it with
single quotes and producing this result.
SELECT * FROM `products` WHERE `name` LIKE '%Harry\\'s Book%'
As you see it is escaping apostrophy to tell it is not end of string
Therefore escaping it with two slashes.One for apostrophy and one for being in single quote.
What you have to do is
Before assigning the parameter to query wrap it with double quotes.
$product_name = "$product->name";
And now pass it to query.
$count = $this->db->like('name', $product_name)->get('products')->num_rows();
The output will be this
SELECT * FROM `products` WHERE `name` LIKE '%Harry\'s Book%'
You see the differece here. It contains single slash now and the record will
be found.
Other answers didn't work for me, this does though:
$count = $this->db->query("SELECT * FROM `default_firesale_products` WHERE `title` LIKE '".addslashes($product['title'])."'")->num_rows();
Whenever CI Active Record mangles your queries you can always just put a raw query in instead and have full control.
Try this, using stripslashes() around $product->name:
$count = $this->db->like('name', stripslashes($product->name))->get('products')->num_rows();
CI automatically escapes characters with active records but I bet that it's already escaped if you entered it previously via active record in CI. So now it is doing a double escape.
Update: You may also want to try adding the following before you query:
$this->db->_protect_identifiers = FALSE;
Last try: try querying this way since it seems like the like active record is causing the error:
$like = $product->name;
$this->db->query("SELECT * FROM `products` WHERE `name` LIKE '%$like%'");