Insert to more than one table with PHP:PDO on MSSQL - php

I'm trying to write a php function which is going to put values to two diferent tables, but it dsn't work. How should I do?
public function AddKursplanering($kursBudgetId, $momentId, $momTypID, $pId, $rollId, $tid, $utfall)
{
if($stmt = $this->m_database->GetPrepareStatement(" INSERT INTO Kursmoment(KBID, MomentID, MomTypID)
VALUES(:kursBudgetId, :momentId, :momTypID)
INSERT INTO Uppgift (KMID, PID, RollID, Tid, Utfall)
VALUES (##IDENTITY, :pId, :rollId, :tid, :utfall)"))
{
$stmt->bindValue(':kursBudgetId', $kursBudgetId,PDO::PARAM_INT);
$stmt->bindValue(':momentId', $momentId,PDO::PARAM_INT);
$stmt->bindValue(':momTypID', $momTypID,PDO::PARAM_INT);
$stmt->bindValue(':pId', $pId,PDO::PARAM_INT);
$stmt->bindValue(':rollId', $rollId,PDO::PARAM_INT);
$stmt->bindValue(':tid', $tid,PDO::PARAM_INT);
$stmt->bindValue(':utfall', $utfall,PDO::PARAM_INT);
if($stmt->execute())
{
$stmt->CloseCursor();
return true;
}
return false;
}
}

If you are getting an error, post the error text
If it is not an error, but it is not working for some reason, state clearly what part doesn't work
Now, that should actually work, but use SCOPE_IDENTITY() instead of ##IDENTITY, which may return you an unrelated number if there are triggers involved.
Also, consider encapsulating such logic in a stored procedure with the parameters, so you can call a single proc that does both inserts (essentially the same code)

Without knowing the error message from the query above it look like you need to have a semi-colon between the statements. Without it, it will be interpreted as one query instead of two.
if($stmt = $this->m_database->GetPrepareStatement("
INSERT INTO Kursmoment(KBID, MomentID, MomTypID)
VALUES(:kursBudgetId, :momentId, :momTypID);
INSERT INTO Uppgift (KMID, PID, RollID, Tid, Utfall)
VALUES (##IDENTITY, :pId, :rollId, :tid, :utfall)"))

Related

PHP & Mysql Syntax incorrect?

I am having an issue with this not running at all when the information is submitted, I believe that I have the syntax wrong.
if ($_POST['note'] != $player->note_text) {
$message = 'Admin '.$user.' has added the note ('.$_POST['note'].') to '.$player->name.'('.$pid.')';
logIt($user, $message, $dbcon);
$note = $_POST['note'];
$note = '"'.$note.'"';
$UpdateN = "INSERT INTO notes (uid, staff_name, name, alias, note_text, warning) VALUES ('$_POST[hidden]', '$user', '$player->name', '$player->aliases', '$note','$_POST[warn]')";
$UpdateN2 = "INSERT INTO players WHERE `playerid` = $_POST[hidden] (warning) VALUES ('$_POST[warn]')";
mysqli_query($dbcon, $UpdateN, $UpdateN2);
The new line I added which seems to have broken it is '$UpdateN2'.
I am not sure if the new line has broken the statement, since I am new to PHP and mysqli any pointers to forums or websites that I can learn and understand this in a more detailed way I would appreciate.
Edit: I have since moved from using mysqli to PDO, I strongly suggestion that anyone willing to start using MYSQL commands with PHP to have a look at this: http://wiki.hashphp.org/PDO_Tutorial_for_MySQL_Developers
I started reading this and testing things out, I find this much more easier but also it looks a lot cleaner and understandable when reading it back after a few days have passed.
In keeping with the mysqli procedural style in the original, using prepared statements with bind placeholders, something like this:
$UpdateN = 'INSERT INTO notes (uid, staff_name, name, alias, note_text, warning)'
. ' VALUES ( ?, ? , ? , ? , ? , ? )';
$UpdateN2 = 'UPDATE players SET warning = ? WHERE playerid = ? ';
if( $sth = mysqli_prepare($dbcon,$UpdateN) ) {
mysqli_stmt_bind_param($sth,'ssssss'
,$_POST['hidden']
,$user
,$player->name
,$player->aliases
,$_POST['note']
,$_POST['warn']
);
if( mysqli_stmt_execute($sth) ) {
// statement execution successful
} else {
printf("Error: %s\n",mysqli_stmt_error($sth));
}
} else {
printf("Error: %s\n",mysqli_error($dbcon));
}
if( $sth2 = mysqli_prepare($dbcon,$UpdateN2) ) {
mysqli_stmt_bind_param($sth2,'ss'
,$_POST['warn']
,$_POST['hidden']
);
if( mysqli_stmt_execute($sth2) ) {
// statement execution successful
} else {
printf("Error: %s\n",mysqli_stmt_error($sth2));
}
} else {
printf("Error: %s\n",mysqli_error($dbcon));
}
If it was me, I'd just make two separate calls to mysqli_query, one for each of your separate queries. PHP has historically been very wary of permitting multiple queries in a single function call, because of possible sql injection vulnerabilities.
On a related note, you need to sanitize your input. $_POST should never, ever, ever appear directly in a mysql query string, because your post data might -actually be something like ')"; DROP TABLE users;'.
Finally, you're using a WHERE clause on an insert. That's probably breaking your query. You should take a couple of days and research how and why that's breaking your query, and how and why to write proper sql queries. Doing so will add value to your company, because your company is less likely to suffer a catastrophic data breach, and it will add value to you, because you'll be a better SQL coder.
Edit: and in the time it took me to write this, three different people made each of those points. LOL.

Insert NULL into database with pdo

in the database I'm working with, there's a table named "packets", in this table there are columns like "id", "userid" etc. and a column named "usage"(I know its a poor choice of name cause usage is a reserved word, but sadly I may not change anything in the table), the type of this column is enum with 3 values("education", "study" and "advanced training") with "education" as default-value and the value can be NULL.
I wrote a class Packet with getters/setters like set_usage($usage)/get_usage() and a class Packet_dao for accessing database using pdo:
class Packet_dao {
private m_insert_query;
...
public function persist($data)
{
$query = $this->m_insert_query;
try
{
$stmt = $this->bind_param($data, $query);
$stmt->execute();
return true;
}
catch (PDOException $ex)
{
$this->m_error_message = $ex->getMessage();
return false;
}
}
private function bind_param($packet, $query)
{
$stmt = $this->m_pdo->prepare($query);
$stmt->bindParam(':userId', $packet->get_user_id());
...
$stmt->bindParam(':usage', $packet->get_usage());
return $stmt;
}
insert query would looks like
INSERT INTO packets (userId, number, ..., `usage`)
VALUES (:userId, Coalesce(:number, default(number)), Coalesce(:usage, default(`usage`)))
so if I want to add a packet into db, the code would looks like:
$packet = new Packet();
$packet_dao = new Packet_dao();
$packet->set_stuff("stuff");
$packet_dao->persist($packet);
so far, so good, everything is working fine.
now, another usage-case "fullversion" should be added, and instead of adding a new value to the enum, they decided to use NULL as value of usage for packets which are full version. Now I get a problem: when I try to set value for usage using $packet->set_usage(NULL), it will be interpreted as the same as if the value isn't set and the default value("education") will be set in this case. What should I do?
apparently, the 2nd parameter of Coalesce() force it to take the default value when nothing is set (or NULL), after I changed Coalesce(:usage, default(usage)) into :usage. It worked

Seemingly identical sql queries in php, but one inserts an extra row

I generate the below query in two ways, but use the same function to insert into the database:
INSERT INTO person VALUES('','john', 'smith','new york', 'NY', '123456');
The below method results in CORRECT inserts, with no extra blank row in the sql database
foreach($_POST as $item)
$statement .= "'$item', ";
$size = count($statement);
$statement = substr($statement, 0, $size-3);
$statement .= ");";
The code below should be generating an identical query to the one above (they echo identically), but when I use it, an extra blank row (with an id) is inserted into the database, after the correct row with data. so two rows are inserted each time.
$mytest = "INSERT INTO person VALUES('','$_POST[name]', '$_POST[address]','$_POST[city]', '$_POST[state]', '$_POST[zip]');";
Because I need to run validations on posted items from the form, and need to do some manipulations before storing it into the database, I need to be able to use the second query method.
I can't understand how the two could be different. I'm using the exact same functions to connect and insert into the database, so the problem can't be there.
below is my insert function for reference:
function do_insertion($query) {
$db = get_db_connection();
if(!($result = mysqli_query($db, $query))) {
#die('SQL ERROR: '. mysqli_error($db));
write_error_page(mysqli_error($db));
} #end if
}
Thank you for any insite/help on this.
Using your $_POST directly in your query is opening you up to a lot of bad things, it's just bad practice. You should at least do something to clean your data before going to your database.
The $_POST variable often times can contain additional values depending on the browser, form submit. Have you tried doing a null/empty check in your foreach?
!~ Pseudo Code DO NOT USE IN PRODUCTION ~!
foreach($_POST as $item)
{
if(isset($item) && $item != "")
{
$statement .= "'$item', ";
$size = count($statement);
$statement = substr($statement, 0, $size-3);
$statement .= ");";
}
}
Please read #tadman's comment about using bind_param and protecting yourself against SQL injection. For the sake of answering your question it's likely your $_POST contains empty data that is being put into your query and resulting in the added row.
as #yycdev stated, you are in risk of SQL injection. Start by reading this and rewrite your code by proper use of protecting your database. SQL injection is not fun and will produce many bugs.

Mysql insert using array

I have an array stored in a variable $contactid. I need to run this query to insert a row for each contact_id in the array. What is the best way to do this? Here is the query I need to run...
$contactid=$_POST['contact_id'];
$eventid=$_POST['event_id'];
$groupid=$_POST['group_id'];
mysql_query($query);
$query="INSERT INTO attendance (event_id,contact_id,group_id) VALUES ('$eventid','$contactid','$groupid')";
Use a foreach loop.
$query = "INSERT INTO attendance (event_id,contact_id,group_id) VALUES ";
foreach($contactid as $value)
{
$query .= "('{$eventid}','{$value}','{$groupid}'),";
}
mysql_query(substr($query, 0, -1));
The idea here is to concatenate your query string and only make 1 query to the database, each value-set is separated by a comma
Since no one hasn't stated that yet, you actually cannot do this:
$query = '
INSERT INTO [Table] ([Column List])
VALUES ([Value List 1]);
INSERT INTO [Table] ([Column List])
VALUES ([Value List 2]);
';
mysql_query($query);
as this has been prevented to prevent sql injections in the mysql_query code. You cannot have semicolon within the given query param with mysql_query. With the following exception, taken from the manual comments:
The documentation claims that "multiple queries are not supported".
However, multiple queries seem to be supported. You just have to pass
flag 65536 as mysql_connect's 5 parameter (client_flags). This value
is defined in /usr/include/mysql/mysql_com.h:
#define CLIENT_MULTI_STATEMENTS (1UL << 16) /* Enable/disable multi-stmt support */
Executed with multiple queries at once, the mysql_query function will
return a result only for the first query. The other queries will be
executed as well, but you won't have a result for them.
That is undocumented and unsupported behaviour, however, and easily opens your code to SQL injections. What you can do with mysql_query, instead, is
$query = '
INSERT INTO [Table] ([Column List])
VALUES ([Value List 1])
, ([Value List 2])
[...]
, ([Value List N])
';
mysql_query($query);
so you can actually insert multiple rows with a one query, and with one insert statement. In this answer there's a code example for it which doesn't concatenate to a string in a loop, which is better than what's suggested in this thread.
However, disregarding all the above, you're probably better of still to use a prepared statement, like
$stmt->prepare("INSERT INTO mytbl (fld1, fld2, fld3, fld4) VALUES(?, ?, ?, ?)");
foreach($myarray as $row)
{
$stmt->bind_param('idsb', $row['fld1'], $row['fld2'], $row['fld3'], $row['fld4']);
$stmt->execute();
}
$stmt->close();
Use something like the following. Please note that you shouldn't be using mysql_* functions anymore, and that your code is suseptible to injection.
for ($i = 0; $i < count($contactid); $i++) {
$query="INSERT INTO attendance (event_id,contact_id,group_id) VALUES ('$eventid','$contactid[$i]','$groupid')";
mysql_query($query);
}
I'm not sure running multiple queries is the best thing to do, so won't recommend making a for loop for example, that runs for each element of the array. I would rather say, make a recursive loop, that adds the new elements to a string, that then gets passed to the query. In case you can give us a short example of your DB structure and how you'd like it to look like (i.e. how the array should go into the table), I could give you an example loop syntax.
Cheers!
What about:
$contactIds = $_POST['contact_id'];
$eventIds = $_POST['event_id'];
$groupIds = $_POST['group_id'];
foreach($contactIds as $key => $value)
{
$currentContactId = $value;
$currentEventId = $eventIds[$key];
$currentGroupId = $groupIds[$key];
$query="INSERT INTO attendance (event_id,contact_id,group_id) VALUES ('$currentEventId','$currentContactId','$currentGroupId')";
mysql_query($query);
}
Well, you could refactor that to insert everything in a single query, but you got the idea.

mysql query insert issue

my query is not inserting and i'm not getting any errors. can't figure out why it's not inserting
foreach($_POST as $key => $value) {
$clean[$key] = mysql_real_escape_string($value);
}
if(isset($_POST['submit'])) {
$entry = "INSERT INTO test (Word, Type, Lang, Country, Gender, Advice, y_Advice, Notes,
EditorNotify, Equiv)
VALUES('".$clean["word_field"]."',
'".$clean["type_field"]."',
'".$clean["lang"]."',
'".$clean["Country"]."',
'".$clean["gender"]."',
'".$clean["advice"]."',
'".$clean["y_advice"]."',
'".$clean["Notes"]."',
'".($clean["Notes"] != '' ? '1' : '')."',
'".$clean["Equiv"]."')";
echo mysql_query ($entry);
mysql_query ($entry);
You're actually doing the insert twice because of this:
echo mysql_query ($entry);
mysql_query ($entry);
The echo line will run the query, and so will the line after it. You need to get rid of that. (though I guess you only put it in there for testing purposes?)
Instead of that, I'd suggest just echoing $entry itself, so you get to see the finished SQL string. You may spot something wrong with the query right away just from that.
If you don't, then try copying+pasting that string into a SQL query program to see what the actual error is. That'll allow you to play with the query until you get it right.
You could also use the PHP command mysql_error() to get the error out of PHP, but it's when you've got a weird SQL error, it can often be quicker and easier to play with the query directly rather than within the PHP code.
hope that helps.
Try replacing:
(Word, Type, Lang, Country, Gender, Advice, y_Advice, Notes,
EditorNotify, Equiv)
With:
(`Word`, `Type`, `Lang`, `Country`,`Gender`, `Advice`, `y_Advice`, `Notes`,
`EditorNotify`, `Equiv`)
You don't know whether you're getting any errors. First, get rid of echo mysql_query(). Then run:
mysql_query($query) or die(mysql_error());
If mysql_query() returns false, which it does upon failure, whatever MySQL error the query generated will now be printed to the screen.
Just a minor note: you should initialize $clean with $clean = array();
If the problem is that the conditional is not firing, then the problem may be elsewhere. Do you have an <input> named "submit" in your form, and is the method of the form post?
Query itself looks okay to me. I think it is difficult to read, so I would do this, but that's just personal style:
$notify = $clean['Notes'] != '' ? '1' : '';
$query = <<<SQL
INSERT INTO test
(Notes, EditoryNotify)
VALUES
($clean[Notes], $notify)
SQL;

Categories