Possible to make this code valid/speed up? - php

I have an enrollment form which takes consumer information, stores it in session, passes from page to page then stores in a database when finished. Originally the table simply listed fields for up to 16 persons but after reading into relational databases, found this was foolish.
I have since created a table named "members" and "managers". Each enrollment will take the information input, store the manager ID in the respective table and place a reference field in each member row containing the manager ID.
While I allow up to 16 members to be enrolled at once, this can range from 1-16.
My best guess is to use a FOR-loop to run though multiple INSERT statements in the event more than 1 member is enrolled.
In the example below, I am using the variable $num to represent the individual member's information and $total to represent the number of all members being enrolled. The code here does not function but am looking for:
a) ways to correct
b) understand if there are more 'efficient' ways of doing this type of INSERT
sample code:
<?php
$conn = mysql_connect("localhost", "username", "pw");
mysql_select_db("db",$conn);
for ($num=1; $num<=$total; $num++) {
$sql = "INSERT INTO table VALUES ('', '$clean_f'.$num.'fname', '$clean_f.$num.mi', '$clean_f.$num.lname', '$clean_f.$num.fednum', '$clean_f.$num.dob', '$clean_f.$num.ssn', '$clean_f.$num.address', '$clean_f.$num.city', '$clean_f.$num.state', '$clean_f.$num.zip', '$clean_f.$num.phone', '$clean_f.$num.email')";
$result = mysql_query($sql, $conn) or die(mysql_error());
}
mysql_close($conn);
header("Location: completed.php");
?>

If all of your statements are structurally the same, but with different parameter values, consider using the PDO extension, which supports prepared statements. The benefits of prepared statements can be read here (http://www.php.net/manual/en/pdo.prepared-statements.php), but in general, the same statement will only need to be compiled once, but can be executed as many times as you want with different parameters, which can make your script more "efficient".
Using PDO, your code could look something like:
$db = new PDO('mysql:host=localhost;dbname=db', 'username', 'pw');
$statement = $db->prepare('INSERT INTO tablename (field1, field2, field3, ...) VALUES (?,?,?,?');
for ($num=1; $num<=$total; $num++) {
$statement->execute(array('val1', 'val2', 'val3', '...'));
}

Generally, putting a query in a loop is bad thing. There is usually a better way. In this case, you should use the multi-insert syntax. Your INSERT isn't working because you didn't specify the fields. I'm assuming the lack of a space between the table name and VALUES is a typo, along with the bad quoting.
INSERT INTO table_name (field1, fname, lname, fednum, ...)
VALUES ('val1', 'Pete', 'Moss', 1234),
('val2', 'T.', 'Cupp', 54321),
('val3', 'Youdid', 'Watt', 787123);

The solution, if I read you right, is to start with the fixed query string:
$queryString = "INSERT INTO table (field1, field2, ...) VALUES ";
then run a loop to build the malleable part. Putting your values into arrays makes things easier:
$queryInsert = '';
$total = count($value1Array);
while ($i < $total) {
$queryInsert .= "('$value1Array[$i]','$value2Array[$i]','$value3Array[$i],...), ";
++$i;
}
then append to the first query piece:
$queryString = $queryString.$queryInsert;
and trim off the trailing , and you're good to go.

Related

How can I insert another row into another table, in PHP?

I can insert the list of questions but the problem is the answer? How
$myQuery= mysql_query("SELECT * FROM tblquestion, tblanswer WHERE questionID='$ctrlnum'");
$numRows = mysql_num_rows($myQuery);
then this will be the insertion of record:
$myQuery = mysql_query("INSERT INTO tblquestion VALUES ( '$ctrlnum','$question1','$question2','$question3','$question4','$question5',
'$question6','$question7','$question8','$question9','$question10') ");
$myQuery= mysql_query("INSERT INTO tblprelimanswer VALUES ('$ctrlnum','$answer1','$answer2','$answer3','$answer4','$answer5', '$answer6','$answer7','$answer8','$answer9','$answer10')
");
How can I insert the answers?
Change the code to
$myQuery = mysql_query("INSERT INTO tblquestion VALUES ($ctrlnum','$question1','$question2','$question3','$question4','$question5','$question6','$question7','$question8','$question9','$question10') ") or die (mysql_error());
$myQuery= mysql_query("INSERT INTO tblprelimanswer VALUES ('$ctrlnum','$answer1','$answer2','$answer3','$answer4','$answer5', '$answer6','$answer7','$answer8','$answer9','$answer10')") or die (mysql_error());
and post back what your error messages are
(This should be a comment but its rather long and easier to read with formatting)
While using a statement of the form
INSERT INTO tblquestion VALUES (...)
will work in MySQL, it is very bad practice not to explicitly state what columns each value maps to. e.g.
INSERT INTO tblquestion ( someId, avalue, adifferentthing ) VALUES (...)
In the relational database model, there is no concept of oredering of attributes within a record. Even on MySQL where such an approach is possible, semantic value is lost by omitting the atribute list and there is a risk of bugs being introduced if the schema is modified.
Further:
'$question1','$question2','$question3','$question4','$question5'....
implies that your data is not normalized. Each question should be in a seperate row.

Why do I get a 500 error? (MySQL php)

<html>
<head>
HTML CODE
<?
$username="xxxxxx";
$password="xxxxxx";
$database="xxxxxx";
mysql_connect(localhost,$username,$password);
$escape = "INSERT INTO monster VALUES ('',$_POST["name"],$_POST["soort"])";
$escape2 = "DELETE monster FROM monster LEFT OUTER JOIN (
SELECT MIN( ID ) AS ID, NAME, PREF
FROM monster
GROUP BY NAME, PREF
) AS KeepRows ON monster.ID = KeepRows.ID
WHERE KeepRows.ID IS NULL";
$query=mysql_real_escape_string($escape);
$query2=mysql_real_escape_string($escape2);
#mysql_select_db($database) or die("MySQL error: Kan inte ansluta till databasen.");
mysql_close();
?>
</body>
</html>
Every time i run this(from another file, containing the name and soort post's) I get an 500 internal server error. First I figured that the queries may be the problem, but they don't even get executed. However, i tried to escape the queries. But still error.
What is wrong with this code? (note: $escape2 is some code i found that removes duplicates in the database. But i don't really know how to format it so that it can be used through php.)
Use something like below...
$query = "INSERT INTO monster VALUES ('', '".$_POST["name"]."', '".$_POST["soort"]."')";
Please do not insert values without escaping.
problem in insert into statement
it should be
$escape = "INSERT INTO monster VALUES ('',".$_POST['name'].",".$_POST['soort'].")";
it is preferable to write colums name while writing insert queries
if column contains string values like VARCHAR or TEXT then use quoted_printable_decode
pass null if column is autoincrement
insert statment
$escape = "INSERT INTO monster (col1, col2, col3) VALUES (NULL,'".$_POST['name']."',".$_POST['soort'].")";
or
$escape = "INSERT INTO monster (col2, col3) VALUES ('".$_POST['name']."',".$_POST['soort'].")";
It looks like you need something like this:
$query = "INSERT INTO monster VALUES ('', '".$_POST["name"]."', '".$_POST["soort"]."')";
Also I would suggest to use prepared statements because it is bad experience to build queries.
First of all I have cool proposition for you. What do you say about some advanced PHP? One step further into great world of safe PHP + MySQL apps?
Introducting to you a PDO. (I know this is not answer to your question but you can consider it). Example of use on your queries:
$db = new PDO('mysql:host=localhost;dbname='.$database, $username, $password);
$insertQuery = $db->prepare('INSERT INTO monster VALUES ("", :name, :soort)');
$deleteQuery = $db->prepare('DELETE monster FROM monster LEFT OUTER JOIN (
SELECT MIN( ID ) AS ID, NAME, PREF
FROM monster
GROUP BY NAME, PREF
) AS KeepRows ON monster.ID = KeepRows.ID
WHERE KeepRows.ID IS NULL');
//to execute query:
$deleteQuery->execute();
//or with params:
$insertQuery->execute(array(
':name' => $_POST['name'],
':soort' => $_POST['soort'],
));
Cool, huh? There is more... Now according to your problem it could be everything (as we don't have error log) but my guess is:
Try to use <?php instead of <?
$escape = "INSERT INTO monster VALUES ('',{$_POST["name"]},{$_POST["soort"]})";
EDIT:
As you provided error log - now I'm sure that problem is in $escape query. It's because you used $escape = " <- and then $_POST["name"] so there was a collision of " (if I can say so).
Try this:
Whenever you insert string type of values in the database using query it has to pass in the quote format. So you just need to change your insert query here.
$query = "INSERT INTO monster VALUES ('', '".$_POST["name"]."', '".$_POST["soort"]."')";
write query like this.
-
Thanks

PDO Move row from one database to another

I have 2 seperate databases with the same structure. I want to move a selected set of rows from one table to another. I am using PDO to select all the rows, then in a while loop I am assuming that I can insert each row into the new table then delete it from the old table.
With normal mysql this is quite a simple task, but I want to use namespaces so that I can easily modify the table structure ect. I have the following working but it does not move the entry to the new table:
try {
$sql = "SELECT * FROM `calls` WHERE `calls`.`status`=0 AND `calls`.`stage` < 4 AND `calls`.`answer` < (NOW() - INTERVAL 10 MINUTE)";
$query = $this->staging->query($sql);
while($row = $query->fetch(PDO::FETCH_ASSOC)) {
$sql = "INSERT INTO `table` (`field1`,`field2`) VALUES (?,?)";
$query = $this->production->prepare($sql);
$query->execute($array);
}
}
catch(PDOException $e) {
$this->informer("FATAL", "Unable to process broken IVR surveys. Error: ".$e->getMessage());
}
You can do it without a while:
INSERT INTO db1.table (fields) SELECT fields FROM db2.table
Of course both databases must be on the same machine
It likely does not work because you are using the question mark placeholder style in the prepared statement, but are passing a named array to execute.
If you name the parameters instead, it should work:
$sql = "INSERT INTO `table` (`field1`,`field2`) VALUES (:field1, :field2)";
Another approach is using federated tables in MySQL to do what you're trying to do. There are some limitations.... but here are the docs to get you going...
http://dev.mysql.com/doc/refman/5.0/en/federated-use.html http://dev.mysql.com/doc/refman/5.0/en/federated-limitations.html

How to return inserted row from INSERT statement with php, SQL SERVER 2005?

What is the easiest / most efficient way to get the entire row inserted after an INSERT statement?
I am pretty sure I could do this as follows:
$aQuery = "INSERT into myTable (a, b, c) VALUES (1, 'Hello', 'Goodbye')";
//the IDENTITY coloumn in myTable is named id
$result = sqlsrv_query($myConn, $aQuery );
if ($result) {
$res = sqlsrv_query('SELECT LAST_INSERT_ID()');
$row = sqlsrv_fetch_array($res);
$lastInsertId = $row[0];
$subQuery = "SELECT * FROM myTable where id = {$lastInsertId}";
$subResult = sqlsrv_query($myConn, $subQuery);
if ($subResult) {
while($subrow = sqlsrv_fetch_array($subResult)) {
echo($subrow ['id'] . ', '.
$subrow ['a'] . ', '.
$subrow ['b']); //etc...
}
}
}
However, I am concerned about the possibility of another insert occurring just before my SELECT LAST_INSERT_ID() and thus messing up my logic to boot. How can I be certain that the last inserted id is truly the INSERT I called previously, and not something happening somewhere else?
Is there a more appropriate way of doing this, perhaps a complete SQL solution (such that the query returns the row automatically rather than using PHP)?
UPDATE: myTable DOES have an explicitly defined (and auto-incremented) identity column, named id.
This will work:
"INSERT into myTable (a, b, c) OUTPUT Inserted.a, Inserted.b, Inserted.c VALUES (1, 'Hello', 'Goodbye')
In Sql Server, you would use select #lastID=SCOPE_IDENTITY()
And #LastID will have the last id inserted for the current scope; therefore, if there was another insertion in the middle, you would still get the correct record on your select.
Never use ##Identity for this or you may end up in a situation like you described.
If you were to use identity field (which maybe you should) there is a command called SCOPE_IDENTIY() which info you can find here:
http://msdn.microsoft.com/en-us/library/ms190315.aspx
Since you do not use it, you do not have to select latest data since you have it when you insert, so just use same data instead of selecting.

How do I get all the ids of the row created by one multiple row insert statement

I'm new to php. So, please forgive me if this seems like a dumb question.
Say i have a MySQL insert statement insert into table (a,b) values (1,2),(3,4),(5,6). table 'table' has a auto increment field called 'id'.
how can I retrieve all the ids created by the insert statement above?
It will be great if i get an example that uses mysqli.
You can't. I would suggest that you maintain your own ids (using guid or your own auto-increment table) and use it when you insert into the table.
But it's possible to get the auto-increment value for the last inserted using LAST_INSERT_ID():
http://dev.mysql.com/doc/refman/5.0/en/getting-unique-id.html
AngeDeLaMort's answer is almost right. Certainly, the most appropriate way to deal with the problem is to insert one row at a time and poll the insert_id or generate the sequence elsewhere (which has additional benefits in terms of scalability).
I'd advise strongly against trying to determine the last insert_id and comparing this the most recent insert_id after the insert - there's just too may ways this will fail.
But...an alternative approach would be:
....
"INSERT INTO destn (id, data, other, trans_ref)
SELECT id, data, other, connection_id() FROM source";
....
"SELECT id FROM destn WHERE trans_ref=connection_id()";
....
"UPDATE destn SET trans_ref=NULL where trans_ref=connection_id()";
The second query will return the ids generated (note that this assumes that you use the same connection for all 3 queries). The third query is necessary because connection ids to go back into the pool when you disconnect (i.e. are reused).
C.
In some cases, if you have another identifier of sort such as a UserID, you could filter your query by UniqueID's greater than or equal to mysql_insert_id(), limit by the number of affected rows and only display those by the user. This would really only work inside of a transaction.
$SQL = "INSERT INTO Table
(UserID, Data)
VALUES
(1,'Foo'),
(1,'Bar'),
(1,'FooBar')";
$Result = mysql_query($SQL);
$LastID = mysql_insert_id();
$RowsAffected = mysql_affected_rows();
$IDSQL = "SELECT RecordID
FROM Table
WHERE UserID = 1
AND RecordID >= '$LastID'
LIMIT '$RowsAffected'";
$IDResult = mysql_query($IDSQL);
as a follow up to AngeDeLaMort:
You could seperate your inserts and do it something like this:
$data = array (
array(1,2),
array(3,4),
array(5,6)
);
$ids = array();
foreach ($data as $item) {
$sql = 'insert into table (a,b) values ('.$item[0].','.$item[1].')';
mysql_query ($sql);
$id[] = mysql_insert_id();
}
Now all your new id's are in the $id array.
Maybe I can do this
$insert = "insert into table (a,b) values (1,2),(3,4),(5,6)";
$mysqli->query($insert);
$rows_to_be_inserted=3;
$inserted_id = $mysqli->insert_id // gives me the id of the first row in my list
$last_row_id = ($inserted_id+$rows_to_be_inserted)-1;
$mysql->query("select * from table where id between $inserted_id and $last_row_id");
what to you guys say?

Categories