I have a problem with executing multiple queries at once with ODBC in PHP.
My code:
$createRowQ = "
declare #myid uniqueidentifier;
set #myid = NEWID();
insert into tps_attachment_data values (#myid, '');
print #myid;
";
$createRow = odbc_prepare($connection, $createRowQ);
odbc_execute($createRow);
$result = odbc_result_all($createRow);
Result:
Variable $result is empty and PHP is giving me this warning with SQL error:
PHP Warning: odbc_execute(): SQL error: [Microsoft][ODBC Driver 13
for SQL Server][SQL Server]46023075-414D-4FF2-87D5-B3B462FE3AF8, SQL
state 01000 in SQLExecute in C:\inetpub\wwwroot\receiver.php on line
656
I think that the problem is in calling multiple statements at once, but I need to declare my ID to be able to print it. Any help would be appreciated.
SQL statement works just fine when I execute it in Management Studio.
PHP version is 7.3.1.
I'm able to reproduce this warning, so the following answer provides a possible solution for this issue. The necessary changes are:
Use SET NOCOUNT ON as first line in your statement to prevent SQL Server from passing the count of rows affected as part of the result set.
Use SELECT #myid AS MyID instead of PRINT #myid to return the generated unique identifier as a result set.
Use odbc_exec() to prepare and execute an SQL statement.
PHP:
<?php
...
$createRowQ = "
SET NOCOUNT ON;
DECLARE #myid uniqueidentifier;
SET #myid = NEWID();
INSERT INTO tps_attachment_data VALUES (#myid, '');
SELECT #myid AS MyID;
--PRINT #myid
";
$result = odbc_exec($connection, $createRowQ);
$line = odbc_fetch_array($result);
echo $line["MyID"];
...
?>
Related
I have been stumped with this and cannot find a working example or tutorial anywhere.
Given the following stored procedure:
SQL
delimiter $$
CREATE PROCECURE sp1(IN 'myoffset' INT, IN 'myrows'
INT)
begin
select * from t1
limit 'myoffset', 'myrows'
END$$
delimiter
I am trying to call it from PHP like so:
... establish $conn, then
PHP
// ver1:
$sql = ( "SET #p0 = $tmp1;" . " SET #p1 = $tmp2;" . "
CALL `sp1`(#p0, #p1);" );
//OR
//ver2
$sql = "SET #p0 = `$tmp1`; SET #p1 = `$tmp2`; CALL
`sp1`(#p0, #p1);";
$result = mysqli_query($conn, $sql);
Neither one works. MariaDB complains that
"Error description: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'SET #p1 = 25; CALL sp1(#p0, #p1)' at line 2"
Any help would be much appreciated!
What is in $tmp1?
If it is a number, then the first one should work, but the second one does not make sense because it becomes
SET #p0 = `1234`;
I assume there is not a column or table named 1234? Keep in mind that backtics are for columns, tables, and database names.
If $tmp is the string "a string", then you get
SET #p0 = a string; -- strings need to be quoted here
or
SET #p0 = `a string`; -- again that is treated as a column (etc) name.
After that, you have another problem: Do not tack multiple statements together (separated by ;); run them separately.
Finally, there is no need for #p0, etc:
$sql = "CALL `sp1`('$tmp1', '$tmp2')";
is sufficient.
Well, not quite. If the values for $tmps came from the outside world, see the dreaded "SQL Injection" problem.
Oh, and what if
$tmp1 = "Don't do this";
Then you get
$sql = "CALL `sp1`('Don't do this', '$tmp2')";
Look at the single quotes. There are 3 of them. How will this be parsed?
I am using MySQLi Object-oriented method for mysqli connection in php. In that, I need a query to rename the table to yesterday's date. How can I do it?
Here is my code:
$stmt = $this->conn->prepare("RENAME TABLE current_table_tmp TO SUBDATE(CURDATE(),1)");
$stmt->execute();
My error:
Fatal error: Call to a member function execute() on boolean
I got answer by using multi_query to execute dynamic SQL statement
Here is my php code:
$location = 'renametable.sql';
$commands = file_get_contents($location);
$this->conn->multi_query($commands);
dynamic SQL statement to append the yesterday date as a renametable.sql file
SET #tablename = 'current_table_tmp';
SELECT #query := CONCAT('RENAME TABLE `', #tablename, '` TO `',
CURDATE(), #tablename, '`');
PREPARE STMT FROM #query;
EXECUTE STMT;
I'm not a newbie to PHP but I have encountered a [seemingly] simple problem which I cannot figure out how to resolve.
MySQL throws error that the syntax is wrong.
My Statement is this:
if($value){
$query = "UPDATE ".$preuploads." SET words = '$words_amount' WHERE id= $sn_id";
$db->sql_query( $query ) or die( mysql_error() );
}
And then $words_amount is an integer, $sn_id is also an integer. They are double checked.
The statement when printed before execution is as follows:
UPDATE SET uploads words = '250' WHERE id= 8081
// edited, with the name of table added since the problem primarily was
// with the encapsulation and the name of table just was dropped in this question
// and not in the app
however words value ('250') is tested with integer data-type as well, but no change occurs and the error lingers on.
And the error thrown is:
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 'SET words = '250' WHERE id= 8081' at line 1
If I understand your question (and preuploads is a table), then
$query = "UPDATE ".$preuploads." SET words = '$words_amount' WHERE id= $sn_id";
should be
$query = "UPDATE ".$preuploads." SET words = '".$words_amount."' WHERE id=".$sn_id;
Or, even better prepare and use bind_param,
$stmt = $mysqli->prepare("UPDATE ? SET words=? WHERE id=?");
$stmt->bind_param($preuploads, $words_amount, $snd_id);
$stmt->execute();
check your string ($words_amount) has any single quotes ' if it is then remove it by using this option on php $words_amount=string_replace("'","/'",$your_string_variable);
I have found two errors:
First, not encapsulation of the data should occur, thus:
$words_count should be left as is, not to be encapsulated with '
And the table and fields name should be encapsulated with backtick
I think your having problem with name of table. The syntax for update query is
UPDATE table_name SET words = '250' WHERE id= 8081
I created a stored procedure like this and called that procedure with input arguments. I want to get the procedure it self while calling it with arguments just like echo query in normal case.
$procedure = "CREATE PROCEDURE pdruser_login(IN userName VARCHAR(300), IN password VARCHAR(500))
BEGIN
DECLARE _sqlQuery VARCHAR(2046);
SET _sqlQuery = 'SELECT login_id, authorized, admin_authorize FROM tbluser_login WHERE user_name = userName AND user_pwd = password AND authorized = 1 AND privacy_policy = 1 AND is_deleted = 0';
SET #sqlQuery = _sqlQuery;
PREPARE dynquery FROM #sqlQuery;
EXECUTE dynquery;
DEALLOCATE PREPARE dynquery;
END;";
if (!mysqli_query($this->con,"DROP PROCEDURE IF EXISTS pdruser_login") ||!mysqli_query($this->con,$procedure))
{
file_put_contents("minefile1.txt", "Stored procedure creation failed: (" . mysqli_errno($this->con) . ") " . mysqli_error($this->con));
}
if (!($result = mysqli_query($this->con,"CALL pdruser_login('".$userName."','".$password."'")))
{
file_put_contents("minefile2.txt","CALL failed: (" . mysqli_errno($this->con) . ") " . mysqli_error($this->con));
}
But the above procedure shows an error "CALL failed: (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 '' at line 1".
How can I display the stored procedure query while calling the stored procedure.Is there is any way for getting the dynamic query so it will be easy to trace the errors in complex queries?
For some reason you don't store your SQL in a variable - so, you cannot have it in your debug info
$sql = "DROP PROCEDURE IF EXISTS pdruser_login";
mysqli_query($this->con,$sql) or trigger_error(mysqli_error($this->con)." [$sql]");
$sql = $procedure;
mysqli_query($this->con,$sql) or trigger_error(mysqli_error($this->con)." [$sql]");
// and so on.
note that trigger_error is a way more useful that file_put_contents. it can put the error in a log file but also it can display it on-screen which id very handy. And it have indispensable file/line stamp
First for creating a MySQL procedure you need to set DELIMITER other than ; then reset delimiter after procedure execution as Inside priocedure all bock should treat as single query but query inside procedure can break sql statement (due to using ;)
Example from mysql site.
DELIMITER //
DROP PROCEDURE IF EXISTS GetAllProducts //
CREATE PROCEDURE GetAllProducts()
BEGIN
SELECT * FROM products;
END //
DELIMITER ;
I've looked around on stackoverflow for a similar question, but haven't found exactly what I was looking for, so here goes. In phpMyAdmin you can have multiple queries in one statement and it executes it for you, eg:'
UPDATE `test` WHERE `test2` = 4;
UPDATE `test` WHERE `test4` = 8;
UPDATE `test` WHERE `test8` = 1;
Now if I try to do something like that in PHP, it doesn't work at all. eg:
$test = 'UPDATE `test` SET `value` = "123" WHERE `test2` = 4;
UPDATE `test` SET `value` = "321" WHERE `test4` = 8;
UPDATE `test` SET `value` = "533" WHERE `test8` = 1;';
mysql_query($test);
Gives and error:
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 '; UPDATE
test SET value = "123" WHERE test2
= 4; UPDATE test SE' at line 1
Is it even possible to combine, say, multiple queries like above, in one statement? I want to do this in the following situation: (The logic behind this is probably very bad, but I don't have much MySQL experience, so please let me know if there's a better way to do it)
The following loops over a couple of times:
function SaveConfig($name, $value)
{
global $sql_save_query;
$sql = 'SELECT * FROM `config` WHERE `name` = "'.$name.'"';
$res = mysql_query($sql);
if($res)
{
$sql_save_query .= 'UPDATE `config` SET value = "'.$value.'" WHERE `name` = "' .$name. '"; '."\n";
}
else
{
$sql_save_query .= 'INSERT INTO `config`(`id`,`name`,`value`) VALUES("","' .$name. '","' .$value. '"); '."\n";
}
}
Then after the loop finishes it runs:
mysql_query($sql_save_query);
Which gives an error:
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 '; UPDATE
config SET value = "" WHERE name =
"fcolour2"; UPDATE config SE' at
line 1
Now my other option (in my mind) is to just execute an SQL query after each loop, one query at a time. But wouldn't that be bad/slow/bad practice?
the php API forbids you to issue multiple queries in a single call to reduce the chance of an SQL injection attack to your code (think of what would happen if I passed '; UPDATE users SET admin=1 WHERE username='hacker' to your login script as username). You need to either execute multiple statements, or wrap the logic of your statements into a single statement (which is not possible in your case).
It's not possible to execute multiple queries using mysql_query.
You can perform multiple inserts at once using this syntax:
INSERT INTO table (col1, col2) VALUES (0, 1), (2, 3), (4, 5); -- Insert 3 rows
In general less queries = better but for updates you just have to do them.
The loop you have in your example is indicative of an architectural problem.
If you are dealing with an existing record, pass the primary key - then you don't need the select at all - you can just run an update statement.
If you are dealing with a new record, pass no key - then you know to run an insert statement.
probably you can use INSERT ... ON DUPLICATE KEY UPDATE
INSERT INTO table (a,b,c) VALUES (1,2,3)
ON DUPLICATE KEY UPDATE c=c+1;
Some other useful links
http://dev.mysql.com/doc/refman/5.0/en/replace.html
http://www.mysqlperformanceblog.com/2007/01/18/insert-on-duplicate-key-update-and-replace-into/
$sqls = explode(";",$test);
foreach ($sqls as $key=>$sql) {
if (strlen(trim($sql))>0) {
mysql_query(trim($sql));
}
}