Control Flow issue in SQL - php

In the php script, there is a variable named $partners_location.
In the SQL there is a column named plocation.
What I want to do is first check if there is any value in the column plocation which matches the value of $partners_location.
If it does match then I want to go ahead and create a new table, from php script itself.
For this type of situation I know what we need is If else, but I don't know how to use it here
This is what I have been trying, by the way I am using PDO.
$dsn= "mysql:dbname=mydatabase";
$name= "root";
$password="****";
$conn = new PDO ($dsn, $name, $password);
...
if($CON = $conn->prepare("SELECT FROM CIDB WHERE plocation='$partners_location'");
$CON->execute();)
{
$tbl=$conn->prepare("CREATE TABLE chat (id INT NOT NULL);
}
else
{
$tbl=$conn->prepare("CREATE TABLE xyz (id INT NOT NULL);
}
I don't think that these if else statements are going to work.
Can someone suggest me something that would work?

$CON->execute() will return true even if the query is successful but zero rows are returned.
Use COUNT() to check if rows exist.
Like this:
$CON = $conn->prepare("SELECT COUNT(*) as cnt FROM CIDB WHERE plocation = '$partners_location'");
$CON->execute();
$row = $CON-> fetch();
if($row[0] != '0' )
$tbl=$conn->prepare("CREATE TABLE chat (id INT NOT NULL)");
else
$tbl=$conn->prepare("CREATE TABLE xyz (id INT NOT NULL)");

Try this:
$CON = $conn->prepare("SELECT COUNT(*) as cnt FROM CIDB WHERE plocation = '$partners_location'");
$CON->execute();
$row = $CON-> fetch();
if($row[0] != '0' )
{
$tbl=$conn->prepare("CREATE TABLE chat (id INT NOT NULL)");
}
else
{
$tbl=$conn->prepare("CREATE TABLE xyz (id INT NOT NULL)");
}
You missed ")

Related

How to return value from stored procedure using PDO on MSSQL database

I have a stored procedure that when called updates few tables and eventually returns an integer value.
When I call this stored procedure using SQL Pro tool, I get back a result as expected. The SQL that is auto-generated by the tool is this;
DECLARE #return_value int
EXEC #return_value =
dbo.GetNextReference
#c_tableName = 'prp',
#c_offYear = 'rcs14'
SELECT
'Return Value' = #return_value
However, I can't seem to get the same results or any results when I try to execute this using PHP PDO driver.
This is my code so far;
$conn = $this->getPDO();
$sql = "CALL GetNextReference (? , ?)";
$stmt = $conn->prepare($sql);
$tbl = 'prp';
$year = "rcs14";
$stmt->execute([$tbl, $year]);
$results = $stmt->fetchAll();
The statement executes without any errors but the results come back as an empty array.
What am I missing?
Sorry, I can't post the actual stored procedure as I am not permitted.
If I understand your question correctly and if you want to check the result of stored procedure execution, you may try with this:
<?php
# Connection
$server = 'server\instance,port';
$database = 'database';
$uid = 'user';
$pwd = 'password';
# Statement
try {
$conn = new PDO("sqlsrv:server=$server;Database=$database", $uid, $pwd);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch( PDOException $e ) {
die( "Error connecting to SQL Server" );
}
try {
$sql = "{? = call GetNextReference (? , ?)}";
# This should work also.
#$sql = "exec ? = GetNextReference (? , ?)";
$spresult = 0;
$tbl = 'prp';
$year = "rcs14";
$stmt = $conn->prepare($sql);
$stmt->bindParam(1, $spresult, PDO::PARAM_INT|PDO::PARAM_INPUT_OUTPUT, PDO::SQLSRV_PARAM_OUT_DEFAULT_SIZE);
$stmt->bindParam(2, $tbl);
$stmt->bindParam(3, $year);
$stmt->execute();
# Next line for single resultset
#$results = $stmt->fetchAll();
# Multiple resultsets
do {
$results = $stmt->fetchAll();
print_r($results, true);
} while ($stmt->nextRowset());
} catch( PDOException $e ) {
die( "Error connecting to SQL Server" );
}
$stmt = null;
$conn = null;
echo 'Stored procedure return value : '.$spresult."</br>";
?>
Op has asked for an example of an OUTPUT parameter. it doesn't specifically answer their question, however, is far too long for a comment:
USE Sandbox;
GO
--Sample Table
CREATE TABLE dbo.TestTable (ID int IDENTITY(1,1),
SomeString varchar(20));
GO
--Sample proc
CREATE PROC dbo.TestSP #SomeString varchar(20), #ID int OUTPUT AS
--You cannot OUTPUT from an INSERT into a scalar variable, so we need a table variable
DECLARE #IDt table(ID int);
INSERT INTO dbo.TestTable (SomeString)
OUTPUT inserted.ID
INTO #IDt
SELECT #SomeString;
--Now set the scalar OUTPUT parameter to the value in the table variable
SET #ID = (SELECT ID FROM #IDt); --this works, as the SP is designed for only one row insertion
GO
DECLARE #SomeString varchar(20) = 'abc', #ID int;
EXEC dbo.TestSP #SomeString = #SomeString,
#ID = #ID OUTPUT; --ID now has the value of the IDENTITY column
--We can check here:
SELECT #ID AS OutputID;
SELECT *
FROM dbo.TestTable;
GO
--Clean up
DROP PROC dbo.TestSP;
DROP TABLE dbo.TestTable;
GO

Create Table In PDO Transaction

How can I fix this transaction so that the pdo query makes a new table in step #4?
The first three steps work, but I can't seem to get #4 to work.
STEPS
Finds a user with a chattingstatus of 0 in the database
Add a user into the database (with predetermined variables)
change the chattingstatus from 0 to 1 for both the user with a 0 status and the inserted user
4. Create a table with the id of both users as the title like this 2+13 (2 being the id and 13 being the id)
$userid = "123456";
$firstname = "Dae";
$oglang = "engs";
$status = 0;
$pdo->beginTransaction();
try{
// Find a user with a status of 0
$sql = "SELECT id FROM users WHERE chattingstatus = :status";
$stmt = $pdo->prepare($sql);
$stmt->execute(array(':status' => $status)
);
$freeuser = $stmt->fetchColumn();
//put the original user into the database with userid firstname and language
$sql = "INSERT INTO users (userid, firstname, oglang, chattingstatus) VALUES (:userid, :firstname, :oglang, :chattingstatus)";
$stmt = $pdo->prepare($sql);
$stmt->execute(array(':userid' => $userid, ':firstname' => $firstname, ':oglang' => $oglang, ':chattingstatus' => 0)
);
$ogID = $pdo->lastInsertId();
// change the chattingstatus of 0 of the free user to 1
$sql = "UPDATE users SET chattingstatus = 1 WHERE id = :freeuser";
$stmt = $pdo->prepare($sql);
$stmt->execute(array(':freeuser' => $freeuser)
);
//query 3 CHANGE STATUS OF ORIGINAL USER from 0 to 1
$sql = "UPDATE users SET chattingstatus = 1 WHERE userid = :oguser";
$stmt = $pdo->prepare($sql);
$stmt->execute(array(':oguser' => $userid)
);
//query 4: Make a table between the 2 users with their IDs
$table = $freeuser."+".$ogID;
$sql ="CREATE table $table(
ID INT( 11 ) AUTO_INCREMENT PRIMARY KEY,
Messages VARCHAR( 50 ) NOT NULL);";
$stmt = $pdo->exec($sql);
print("Created $table Table.\n");
$pdo->commit();
}
//Our catch block
catch(Exception $e){
//Print out the error message.
echo $e->getMessage();
//Rollback the transaction.
$pdo->rollBack();
}
Thanks in advance.
Since your table name includes the special character +, you need to put it in backticks to quote it.
$sql ="CREATE table `$table` (
ID INT( 11 ) AUTO_INCREMENT PRIMARY KEY,
Messages VARCHAR( 50 ) NOT NULL);";
You'll need to remember to put backticks around the table name whenever you use it in other queries. If you insist on having per-user tables like this, you might want to use a different character to connect them, like underscore.
Creating table in transation doesn't work in MySQL:
Some databases, including MySQL, automatically issue an implicit COMMIT when a database definition language (DDL) statement such as DROP TABLE or CREATE TABLE is issued within a transaction. The implicit COMMIT will prevent you from rolling back any other changes within the transaction boundary.
Source: https://www.php.net/manual/en/pdo.begintransaction.php

MS SQL 2005 Auto Increment Error

So, I have tried to create a table inside my database 'Test',
CREATE TABLE TestTbl(
id INT IDENTITY(1,1),
Agent_id VARCHAR(255) NOT NULL
)
After it was created, I tried to add 2 values for the agent via php, but the result is this:
id | Agent_id
0 8080
0 8081
It does not auto increment, even if I set 'id' as a Primary key, still the problem occurs, anyone knows how to solve this problem?
Here is my insert statement in php, nevermind the $conn, because it works, it is for my sql connection
if(isset($_POST['agentid'])){
$agent = $_POST['agentid'];
$query = "SELECT * FROM [Test].[dbo].[TestTbl] WHERE [Agent_id] = '$agent'";
$result = sqlsrv_query($conn,$query);
if(sqlsrv_has_rows($result) !=0){
echo "ID EXISTS";
}else{
$sql = "SET INDENTITY_INSERT TestTbl ON
INSERT INTO [Test].[dbo].[TestTbl]
([id],[Agent_id]) VALUES ('','$agent')
SET IDENTITY_INSERT TestTbl OFF";
echo "Added";
}}
Change this part
From
INSERT INTO [Test].[dbo].[TestTbl]
([id],[Agent_id]) VALUES ('','$agent')
To
INSERT INTO [Test].[dbo].[TestTbl]
([Agent_id]) VALUES ('$agent')
When it's auto increment, you don't' need to specify that in your INSERT statement.
Also do not SET IDENTITY_INSERT to OFF when you want to use auto increment feature of your table
SET IDENTITY_INSERT allows explicit values to be inserted into the identity column of a table.
Your complete query
if(isset($_POST['agentid'])){
$agent = $_POST['agentid'];
$query = "SELECT * FROM [Test].[dbo].[TestTbl] WHERE [Agent_id] = '$agent'";
$result = sqlsrv_query($conn,$query);
if(sqlsrv_has_rows($result) !=0){
echo "ID EXISTS";
}else{
$sql = "INSERT INTO [Test].[dbo].[TestTbl]
([Agent_id]) VALUES ('$agent')";
echo "Added";
}}

PDO with table prefix

I have the follow Model class, which all my models extends.
class Model {
[...]
protected static $_query; // Query preparated
public function prepare($query = null) {
[...] // Connect to PDO, bla bla bla
self::$_query = self::$link->prepare($query);
}
[...]
}
class Login extends Model {
public function getUser($username = null) {
self::prepare('SELECT * FROM usuarios WHERE usuario = :username LIMIT 1');
self::bindValue('username', $username);
return self::fetch();
}
}
The problem is, I need to insert prefix to my mysql, to avoid table conflicts, but don't want to edit all my querys.
clientone_tablename
clienttwo_tablename
clientthree_tablename
How I can do this, parse and insert table prefix when prepare the query?
I have not tried nothing because what I know is, extend my custom PDO to PHP PDO class, which is not much now..
I have seen this: PDO - Working with table prefixes. But don't worked propertly..
Thanks!
So i've assume you have only 1 MySQL database (minimum package on your webhost) and need to store a copy of a system for each of your clients.
What I was suggesting, is that you create a separate set of tables as you already are (for each client), but the name wont matter because you have a look-up of the table names in your clients table.
Heres my example for you: The clients table should store the table names of their own tables
(e.g. users_tbl = clientone_users for client id:1) So that later on you can just query the clients table and get his/her table names, then use that result to query on his/her user, news, pages, and files tables.
# SQL: new table structure
-- store the names of the clients tables here
CREATE TABLE clients(
id INT NOT NULL AUTO_INCREMENT,
PRIMARY KEY(id),
name VARCHAR(50),
address VARCHAR(250),
email VARCHAR(50),
pass BLOB,
/* table names*/
users_tbl VARCHAR(70),
news_tbl VARCHAR(70),
pages_tbl VARCHAR(70),
files_tbl VARCHAR(70)
) ENGINE = InnoDB;
# PHP: Some definitions for the table structure
$tbl_names = array("_users","_news","_pages","_files");
$tbl_fields = array();
$tbl_fields[0] = array("id INT","users_col1 VARCHAR(10)","users_col2 VARCHAR(20)");
$tbl_fields[1] = array("id INT","news_col1 DATE",...);
$tbl_fields[2] = array(...);
$tbl_fields[3] = array(...);
// refers to YOUR clients table field names (see above)
$clients_fields = array("users_tbl", "news_tbl", "pages_tbl", "files_tbl");
# PHP: Create a user and create the users database
function createUser($name, $address, $email, $pass, $salt) {
global $db, $tbl_names, $tbl_fields;
$success = false;
if ($db->beginTransaction()) {
$sql = "INSERT INTO clients(name, address, email, pass)
VALUES (?, ?, ?, AES_ENCRYPT(?, ?));"
$query = $db->prepare($sql);
$query->execute(array($name, $address, $email, $pass, $salt));
if ($query->rowCount() == 1) { # if rowCount() doesn't work
# get the client ID # there are alternative ways
$client_id = $db->lastInsertId();
for ($i=0; $i<sizeof($tbl_names); $i++) {
$client_tbl_name = $name . $tbl_names[$i];
$sql = "CREATE TABLE " . $client_tbl_name . "("
. implode(',', $tbl_fields[$i]) . ");";
if (!$db->query($sql)) {
$db->rollBack();
return false;
} else {
$sql = "UPDATE clients SET ".clients_fields[$i]."=? "
."WHERE id=?;";
$query = $db->prepare($sql);
if (!$query->execute(
array($client_tbl_name, (int)$client_id)
)) {
$db->rollBack();
return false;
}
}
}
$db->commit();
$success = true;
}
if (!$success) $db->rollBack();
}
return $success;
}
# PHP: Get the Client's table names
function getClientsTableNames($client_id) {
$sql = "SELECT (users_tbl, news_tbl, pages_tbl, files_tbl)
FROM clients WHERE id=?;";
$query = $db->prepare($sql);
if ($query->execute(array((int)$client_id)))
return $query->fetchAll();
else
return null;
}
# PHP: Use the table name to query it
function getClientsTable($client_id, $table_no) {
$table_names = getClientsTableNames($client_id);
if ($table_names != null && isset($table_names[$table_no])) {
$sql = "SELECT * FROM ".$table_names[$table_no].";";
$query = $db->prepare($sql);
if ($query->execute(array((int)$client_id)))
return $query->fetchAll();
}
return null;
}
Just rewrite your queries to use a table prefix found in a variable somewhere. Parsing all your queries for tablenames is more trouble than it is worth. (Do you really want to write an SQL parser?)

PHP/MYSQL - Check whether it have duplicated record before inserting new record

Suppose I have a table called "device" as below:
device_id(field)
123asf15fas
456g4fd45ww
7861fassd45
I would like to use the code below to insert new record:
...
$q = "INSERT INTO $database.$table `device_id` VALUES $device_id";
$result = mysql_query($q);
...
I don't want to insert a record that is already exist in the DB table, so how can I check whether it have duplicated record before inserting new record?
Should I revise the MYSQL statement or PHP code?
Thanks
UPDATE
<?php
// YOUR MYSQL DATABASE CONNECTION
$hostname = 'localhost';
$username = 'root';
$password = '';
$database = 'device';
$table = 'device_id';
$db_link = mysql_connect($hostname, $username, $password);
mysql_select_db( $database ) or die('ConnectToMySQL: Could not select database: ' . $database );
//$result = ini_set ( 'mysql.connect_timeout' , '60' );
$device_id = $_GET["device_id"];
$q = "REPLACE INTO $database.$table (`device_id`) VALUES ($device_id)";
$result = mysql_query($q);
if (!$result) {
die('Invalid query: ' . mysql_error());
}
?>
Since I understood well your question you have two ways to go, it depends how you would like to do the task.
First way -> A simple query can returns a boolean result in the device_id (Exists or not) from your database table. If yes then do not INSERT or REPLACE (if you wish).
Second Way -> You can edit the structure of your table and certify that the field device_id is a UNIQUE field.
[EDITED]
Explaining the First Way
Query your table as follow:
SELECT * FROM `your_table` WHERE `device_id`='123asf15fas'
then if you got results, then you have already that data stored in your table, then the results is 1 otherwise it is 0
In raw php it looks like:
$result = mysql_query("SELECT * FROM `your_table` WHERE `device_id`='123asf15fas'");
if (!$result)
{
// your code INSERT
$result = mysql_query("INSERT INTO $database.$table `device_id` VALUES $device_id");
}
Explaining the Second Way
If your table is not yet populated you can create an index for your table, for example go to your SQL command line or DBMS and do the follow command to your table:
ALTER TABLE `your_table` ADD UNIQUE (`device_id`)
Warning: If it is already populated and there are some equal data on that field, then the index will not be created.
With the index, when someone try to insert the same ID, will get with an error message, something like this:
#1062 - Duplicate entry '1' for key 'PRIMARY'
The best practice is to use as few SQL queries as possible. You can try:
REPLACE INTO $database.$table SET device_id = $device_id;
Source

Categories