Somewhat new to odbc_prepare statements and am having an issue when trying to execute a stored procedure that requires datetime input parameters.
If I am to execute using odbc without using the prepared statement as displayed below I have no issue...
$dblink = db_connect();
$query = "EXEC dbo.[ProcedureName] '" . $dateinput . "'";
odbc_exec($dblink, $query);
Using the odbc_prepare I'm getting an error (only for procedures with DateTime inputs parameters). Example below...
function execute_db($dblink, $query, $params){
$n = sizeof($params);
for($i=0; $i<$n; $i++){
if($i != 0){
$query = $query . ', ?';
}
else{
$query = $query . ' ?';
}
}
$statement = odbc_prepare($dblink, $query);
odbc_execute($statement, $params);
return $statement;
}
$dblink = db_connect();
$query = "EXEC dbo.[ProcedureName]";
$params = array($dateinput);
$result = execute_db($dblink, $query, $params);
This returns the following error:
Warning: odbc_execute(): SQL error: [Microsoft][ODBC SQL Server
Driver]Invalid character value for cast specification, SQL state 22005
in SQLExecute
The date string I'm passing in is in 'mm/dd/yyyy' format and works fine without using prepare. Is there a workaround for this other than changing the stored procedure's input type?
Use the proper ODBC syntax for calling a procedure and use the proper syntax for date times and it might get you further. The call syntax is {call procname(arguments)}. The datetime syntax is {ts ''} - see Date, Time, and Timestamp Escape Sequences and ODBC Datetime Format
Related
I want to bind Values to a SQL Statement using a PDO connection to an SQL Server via ODBC.
If I execute the statement without a parameter I get a result but if I want to bind a parameter to that sql I get a "Function sequence error" thrown back.
$fromDate = strval(date('Y-d-m'))." 00:00:00.000";
//works
$sql = "SELECT a.FromDate FROM Absence a WHERE a.FromDate > '".$fromDate."'";
$arrParams = [];
runStatement($sql, $arrParams);
//don't work
$sql = "SELECT a.FromDate FROM Absence a WHERE a.FromDate > :fromdate1";
$arrParams = [':fromdate1' => $fromDate];
runStatement($sql, $arrParams);
//thats how I bind the parameters
function runStatement($sql, $arrParams)
{
$stmt = $this->conn->prepare($sql);
foreach($arrParams as $key => $value)
{
$stmt -> bindValue($key, $value);
}
$stmt -> execute();
return $stmt -> fetchAll(PDO::FETCH_ASSOC);
}
I tried to bind the values with bindParam() but the error remains the same. On Sqlite and Ingres Database the bindValue() works fine for me.
I am using PHP 8.x and SQL Server 2012. Installing the php drivers for SQL doesn't work here.
Edit: I could narrow down the error to the date type. Because in the where clause I want to compare two dates.
When I try other statements without dates as binded params the statement works fine.
So the comparison of the datetype is the error here.
I'm new to OCI, but just trying to do a basic oci_bind_by_name in PHP to get it working. But even with a simple select statement and a dummy variable, it rejects the variable type.
Here's the code:
$conn = oci_connect($username, $password, $database);
$dummy = "dummy#dummy.com";
$u = oci_parse($conn, "select ca_email from pwv_google_group");
oci_bind_by_name($u, ':ca_email', $dummy);
But it just returns:
Warning: oci_bind_by_name(): ORA-01036: illegal variable name/number
Since this is a very simple query/parameter, I can only assume my syntax is wrong or something might be off on the Oracle side (ca_email really should be a varchar, but I'm using Datagrip which doesn't allow DESC command, so I don't know how to validate that). Is something else wrong?
oci_bind_by_name() is expecting you to bind a value for some form of input to the SQL statement - from the manual
bv_name The colon-prefixed bind variable placeholder used in the
statement. The colon is optional in bv_name. Oracle does not use
question marks for placeholders.
So for your example, it would be more like
$u = oci_parse($conn, "select * from pwv_google_group where ca_email = :ca_email");
oci_bind_by_name($u, ':ca_email', $dummy);
As you are trying to retrieve the values from the data you just need to fetch the data as in (hacked from example #3 in manual)
$u = oci_parse($conn, 'select ca_email from pwv_google_group');
oci_execute($u);
$row = oci_fetch_array($u, OCI_ASSOC+OCI_RETURN_NULLS);
foreach ($row as $item) {
print $item."<br>\n";
}
I've made a PDO database class which I use to run queries on an MS Access database.
When querying using a date condition, as is common in SQL, dates are passed as a string. Access usually expects the date to be surrounded in hashes however. E.g.
SELECT transactions.amount FROM transactions WHERE transactions.date = #2013-05-25#;
If I where to run this query using PDO I might do the following.
//instatiate pdo connection etc... resulting in a $db object
$stmt = $db->prepare('SELECT transactions.amount FROM transactions WHERE transactions.date = #:mydate#;'); //prepare the query
$stmt->bindValue('mydate', '2013-05-25', PDO::PARAM_STR); //bind the date as a string
$stmt->execute(); //run it
$result = $stmt->fetch(); //get the results
As far as my understanding goes the statement that results from the above would look like this as binding a string results in it being surrounded by quotes:
SELECT transactions.amount FROM transactions WHERE transactions.date = #'2013-05-25'#;
This causes an error and prevents the statement from running.
What's the best way to bind a date string in PDO without causing this error? I'm currently resorting to sprintf-ing the string which I'm sure is bad practise.
Edit: if I pass the hash-surrounded date then I still get the error as below:
Fatal error: Uncaught exception 'PDOException' with message
'SQLSTATE[22018]: Invalid character value for cast specification:
-3030 [Microsoft][ODBC Microsoft Access Driver] Data type mismatch in criteria expression. (SQLExecute[-3030] at
ext\pdo_odbc\odbc_stmt.c:254)' in
C:\xampp\htdocs\ips\php\classes.php:49 Stack trace: #0
C:\xampp\htdocs\ips\php\classes.php(49): PDOStatement->execute() #1
C:\xampp\htdocs\ips\php\classes.php(52): database->execute() #2
C:\xampp\htdocs\ips\try2.php(12): database->resultset() #3 {main}
thrown in C:\xampp\htdocs\ips\php\classes.php on line 49
Normally when using a prepared statement or a parameterized query you don't need to worry about delimiting string and date values; all of that is handled for you "behind the scenes".
I just tried the following and it worked for me:
<?php
$connStr =
'odbc:Driver={Microsoft Access Driver (*.mdb, *.accdb)};' .
'Dbq=C:\\Users\\Gord\\Desktop\\Database1.accdb;' .
'Uid=Admin;Pwd=;';
$dbh = new PDO($connStr);
$sql =
"INSERT INTO tblDateTest (dateCol) VALUES (?)";
$newDateTimeValue = "2013-06-30 17:18:19";
$sth = $dbh->prepare($sql);
if ($sth->execute(array($newDateTimeValue))) {
echo "Done\r\n";
}
else {
$arr = $sth->errorInfo();
print_r($arr);
}
You should put your date (entire value) in the bindValue method. Example:
$stmt = $db->prepare('SELECT transactions.amount FROM transactions WHERE transactions.date = :mydate'); //prepare the query
$stmt->bindValue('mydate', '#2013-05-25#', PDO::PARAM_STR); //bind the date as a string
I'm trying to use prepared statements to do a simple insert with PHP and Postgres. So far, I've done this:
<?php
$conn_string = "host=localhost port=5432"; // plus us/pw
$dbconn = pg_connect($conn_string);
$table = 'business_primary_category';
$column = 'primary_category';
$tag = 'restuarant';
// Prepare a query for execution
$result = pg_prepare($dbconn, "my_query", 'SELECT * FROM $table WHERE $column = $1');
// Execute the prepared query. Note that it is not necessary to escape
// the string "Joe's Widgets" in any way
$result = pg_execute($dbconn, "my_query", array("$tag"));
?>
I've taken it basically from the page on php.net, and can't figure out what I've done wrong. Do I need to install a library to use it or something. Thanks!
These are the errors I get:
Warning: pg_prepare() [function.pg-prepare]: Query failed: ERROR: syntax error at or near "$" at character 15 in /home/url **......** pdo.php on line 11
Warning: pg_execute() [function.pg-execute]: Query failed: ERROR: prepared statement "my_query" does not exist in /home/url **......** pdo.php on line 15
Warning: pg_execute() [function.pg-execute]: Query failed: ERROR: prepared statement "my_query" does not exist in /home/url **......** pdo.php on line 18
If you want your variables to be interpolated, then you need to use double quotes; else PHP treats it as a string literal. Try:
$result = pg_prepare($dbconn, "my_query", "SELECT * FROM $table WHERE $column = $1");
First thing that jumps out... Use double quotes on 'SELECT * FROM $table WHERE $column = $1'.
I am having trouble with using PHP PDO interface with Microsoft SQL Server. The problem is with converting PHP number values to use in functions of MS SQL Server. I use the following statement to delete certain records:
$sql = "DELETE FROM table WHERE SUBSTRING(attribute, 1, ?) = ?";
I prepare and execute this statement with code (a little shrinked):
$query = $pdo->prepare ($sql);
$query->execute (array (strlen ('Text'), 'Text'));
But the query always fails. The error is:
SQLSTATE[42000]: [Microsoft][SQL Server Native Client 11.0][SQL Server]Argument data type nvarchar is invalid for argument 3 of substring function.
I am assuming the number from strlen is not parsed into a number, but I don't know how to fix this (except to manually add into the query).
I have found these links, however not very helpful.
http://social.msdn.microsoft.com/Forums/en-US/sqldriverforphp/thread/0f09ac5e-62cd-4ccf-b2cb-848aad23811e
http://drupal.org/node/1169202
The guys on Drupal had same error, but they fixed it with recreating function with casts. Is there any other way to fix this?
Thanks.
Not sure if this will solve it, but try something like this
$length = strlen('Text');
$text = "Text";
$sql = "DELETE FROM table WHERE SUBSTRING(attribute, 1, :len) = :text";
$query = $pdo->prepare ($sql);
$query->bindParam(':len', $length, PDO::PARAM_INT);
$query->bindParam(':text', $text, PDO::PARAM_STR);
$query->execute();
Try:
$query = $pdo->prepare ($sql);
$query->execute (array ((int) strlen ('Text'), 'Text'));