I am generating a table in HTML from a MySQL database, so that stored data can be displayed on a web page, and ultimately downloaded as a spread sheet.
I have a large set of SQL headers (probably the wrong name for this), that is to say the 'Title' of any given column.
I am using SELECT to get the data from MySQL via PDO:
$sql ="
SELECT
`sv_20` AS `Name`,
`sv_21` AS `Age`,
`sv_22` AS `Height`,
`sv_23` AS `Weight`,
...
...
`sv_999` AS `Something`
FROM
database.table";
In PHP I would define two arrays (the database headers and the titles I'd like them to have) and then write a foreach loop saying:
foreach(array_combine($headers, $titles) as $header => $title)
{
echo "`$header` AS `$title`,";
}
Which would give me the complete set of calls, is there a way to do this in SQL when querying a database? Thank you
It's basic string manipulation, instead of echo, you want to append this to the string with $sql .=
You'll have some problems with the extra comma after the last item, it's better to
$sql = array();
foreach(....)
$sql[] = "`$header` AS `$title`";
and then do a join(',', $sql);
Related
This question's answers are a community effort. Edit existing answers to improve this post. It is not currently accepting new answers or interactions.
Is the database query faster if I insert multiple rows at once:
like
INSERT....
UNION
INSERT....
UNION
(I need to insert like 2-3000 rows)
INSERT statements that use VALUES syntax can insert multiple rows. To do this, include multiple lists of column values, each enclosed within parentheses and separated by commas.
Example:
INSERT INTO tbl_name
(a,b,c)
VALUES
(1,2,3),
(4,5,6),
(7,8,9);
Source
If you have your data in a text-file, you can use LOAD DATA INFILE.
When loading a table from a text file, use LOAD DATA INFILE. This is usually 20 times faster than using INSERT statements.
Optimizing INSERT Statements
You can find more tips on how to speed up your insert statements on the link above.
Just use a SELECT statement to get the values for many lines of the chosen columns and put these values into columns of another table in one go. As an example, columns "size" and "price" of the two tables "test_b" and "test_c" get filled with the columns "size" and "price" of table "test_a".
BEGIN;
INSERT INTO test_b (size, price)
SELECT size, price
FROM test_a;
INSERT INTO test_c (size, price)
SELECT size, price
FROM test_a;
COMMIT;
The code is embedded in BEGIN and COMMIT to run it only when both statements have worked, else the whole run up to that point gets withdrawn.
Here is a PHP solution ready for use with a n:m (many-to-many relationship) table :
// get data
$table_1 = get_table_1_rows();
$table_2_fk_id = 123;
// prepare first part of the query (before values)
$query = "INSERT INTO `table` (
`table_1_fk_id`,
`table_2_fk_id`,
`insert_date`
) VALUES ";
//loop the table 1 to get all foreign keys and put it in array
foreach($table_1 as $row) {
$query_values[] = "(".$row["table_1_pk_id"].", $table_2_fk_id, NOW())";
}
// Implode the query values array with a coma and execute the query.
$db->query($query . implode(',',$query_values));
EDIT : After #john's comment I decided to enhance this answer with a more efficient solution :
divides the query to multiple smaller queries
use rtrim() to delete last coma instead of implod()
// limit of query size (lines inserted per query)
$query_values = "";
$limit = 100;
$table_1 = get_table_1_rows();
$table_2_fk_id = 123;
$query = "INSERT INTO `table` (
`table_1_fk_id`,
`table_2_fk_id`,
`insert_date`
) VALUES ";
foreach($table_1 as $row) {
$query_values .= "(".$row["table_1_pk_id"].", $table_2_fk_id, NOW()),";
// entire table parsed or lines limit reached :
// -> execute and purge query_values
if($i === array_key_last($table_1)
|| fmod(++$i / $limit) == 0) {
$db->query($query . rtrim($query_values, ','));
$query_values = "";
}
}
// db table name / blog_post / menu / site_title
// Insert into Table (column names separated with comma)
$sql = "INSERT INTO product_cate (site_title, sub_title)
VALUES ('$site_title', '$sub_title')";
// db table name / blog_post / menu / site_title
// Insert into Table (column names separated with comma)
$sql = "INSERT INTO menu (menu_title, sub_menu)
VALUES ('$menu_title', '$sub_menu', )";
// db table name / blog_post / menu / site_title
// Insert into Table (column names separated with comma)
$sql = "INSERT INTO blog_post (post_title, post_des, post_img)
VALUES ('$post_title ', '$post_des', '$post_img')";
I'm relatively new to MYSQL and am having trouble combining idea I have read about. I have a form generated from a query. I want to be able to insert or update depending on whether there is currently a matching row. I have the following code which works for inserting but I;m struggling with the On DUPLICATE UPDATE part I keep getting a message saying there is an error in my syntax or unexpeted ON depending on how I put the ' .
require_once("connect_db.php");
$row_data = array();
foreach($_POST['attendancerecordid'] as $row=>$attendancerecordid) {
$attendancerecordid=mysqli_real_escape_string($dbc,$attendancerecordid);
$employeeid=mysqli_real_escape_string($dbc,($_POST['employeeid'][$row]));
$linemanagerid=mysqli_real_escape_string($dbc,($_POST['linemanagerid'][$row]));
$abscencecode=mysqli_real_escape_string($dbc,($_POST['abscencecode'][$row]));
$date=mysqli_real_escape_string($dbc,($_POST['date'][$row]));
$row_data[] = "('$attendancerecordid', '$employeeid', '$linemanagerid', '$abscencecode', '$date')";
}
if (!empty($row_data)) {
$sql = 'INSERT INTO attendance (attendancerecord, employeeid, linemanagerid, abscencecode, date) VALUES '.implode(',', $row_data)
ON DUPLICATE KEY UPDATE abscencecode = $row_data[abscencecode];
echo $sql;
$result = mysqli_query ($dbc, $sql) or die(mysqli_error ($dbc));
}
The various echo statements are showing that the correct data is coming through and my select statement was as expected before I added in the ON DUPLICATE statement.
You need to fix the way the sql statement is constructed via string concatenation. When you create an sql statement, echo it and run it in your favourite mysql manager app for testing.
$sql = 'INSERT INTO attendance (attendancerecord, employeeid, linemanagerid, abscencecode, date) VALUES ('.implode(',', $row_data).') ON DUPLICATE KEY UPDATE abscencecode = 1'; //1 is a fixed value yiu choose
UPDATE: Just noticed that your $row_data array does not have named keys, it just contains the entire new rows values as string. Since you do bulk insert (multiple rows inserted in 1 statement), you have to provide a single absencecode in the on duplicate key clause, or you have to execute each row in a separate insert to get the absence code for each row in a loop.
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.
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.
how to add multiple records in mysql using php. Is using array the only solution to this problem. Because I tried using array but the record that would be added in the database would look like this:
array
You can use a multivalue insert statement (INSERT... VALUES (record1), (record2) etc)
(see http://dev.mysql.com/doc/refman/5.1/en/insert.html)
This is how you can construct such a statement from array of records
$values = array();
foreach($records_array as $record)
$values[] = sprintf("( '%s' , '%s' )", addslashes($record['name']), addslashes($record['email']));
$sql = "INSERT INTO users(name, email) VALUES " . implode(",", $values);
mysql_query($sql);
You need to go through each member of the array:
foreach($array as $record)
{ ... }
and perform an INSERT query for each member or - better for performance - insert all records in one statement as outlined in user187291's answer.