有没有办法使用PHP进行dymanic插入功能?
我有一个函数可以处理几个遵循相同结构的文件,但并不总是具有相同数量的值。例如,如果一个文件有10个值,它将写入某个表,如果它有3,它将写入另一个表。
我考虑过一个开关块,这个伪代码就行了:
function($table)
{
$n_values = (number of values read from the file);
switch($n_values)
{
case 1: $query = "INSERT INTO ".$table." VALUES('')";
break;
case 2: $query = "INSERT INTO ".$table." VALUES('', '')";
break;
(...)
}
$query->run();
}
但是,此块仅处理硬编码的情况。我想知道是否有办法操纵查询并将其设置为适应从文件读取的值的数量并指定写入正确的表?
编辑:我设法开发了我想要的动态系统,有可能将我想要的值附加到字符串然后运行字符串。我稍微更改了代码(只有处理这个主题的部分在这里),所以如果复制和粘贴它应该不起作用,但是我知道我是如何做到的。为答案喝彩。 function func($table)
{
open_file($file_name);
//while (!$file_name->eof())
{
$line = explode(" ", trim($file->fgets()));
$query = "INSERT INTO `".$table."` VALUES ('' "; //1st value is an a.i. id
for($i = 0 ; $i < get_num_values($file_name)); $i++)
{
$query = $query.', ' .$line[($i)]. '';
}
$query = $query . ')';
$stmt = $con->query($query);
}
}
答案 0 :(得分:0)
听起来您需要各种INSERT语句,可以根据输入文件中显示的数据项数(可能是数据项的类型)自动识别使用哪个表。
你的问题的答案:不,SQL没有这样做。
根据您的问题,您可以很好地创建一个特定于您的应用程序的客户端程序,该程序将执行您想要的操作。编写自己的程序是正确的方法:您可以通过了解应用程序的详细信息来控制表选择逻辑和错误处理。
答案 1 :(得分:0)
基于数组的方法
使用基于数组的方法,而不是在字段中附加数字:
<form action="" method="POST">
<b>Product 1</b><br
<label>Product Id <input type="text" name="products[0][id]"></label>
<br>
<label>Product Type <input type="text" name="products[0][type]"></label>
<br>
<b>Product 2</b><br>
<label>Product Id <input type="text" name="products[1][id]"></label>
<br>
<label>Product Type <input type="text" name="products[1][type]"></label>
</form>
现在,如果您要将此内容提交给PHP并执行print_r($ _ POST [&#39; products&#39;]);,您将获得以下内容:
array(
0 => array(
'id' => '...',
'type' => '...',
),
1 => array(
'id' => '...',
'type' => '...',
)
)
这允许您为插入执行一次逻辑,然后使用循环来执行所有字段。
(伪)代码如下:
$products = (isset($_POST['products']) && is_array($_POST['products'])) ? $_POST['products'] : array();
//Note that I've assumed the id column is an int, and the type column is a string.
//In real schema, I would expect type to also be an int, but I want to illustrate proper escaping.
//(There is more on this in a later section)
$query = "INSERT INTO products (id, type) VALUES (%d, '%s')";
foreach ($products as $product) {
//Ensure that $product contains a valid entry, and if it does not, store errors somewhere
if (valid entry) {
$res = mysql_query(sprintf($query, (int) $product['id'], mysql_real_escape_string($product['type'])));
if (!$res) {
//Log an error about the query failing
}
}
}
答案 2 :(得分:0)
可能的解决方案。
这使用一个数组存储每个列数的表名。
它还使用一个类一次插入多行(在一个insert语句中插入250行比执行250个单独插入要快得多)。
它循环遍历表列表并为每个表创建一个新实例。
然后它读取文件。对于每一行,它为具有该列数的文件调用对象的make_row方法。当对象的类要插入一定数量的行时(默认情况下为255 - 易于更改),它将执行插入,并且在调用__DESTRUCT时也会执行插入。
输入文件完成后,它会围绕表格对象循环并将它们全部取消(这会触发每个的__DESTRUCT,清除所有剩余的插入)。
<?php
$table_names = array(1=>'Table1Col', 2=>'Table2Col', 3=>'Table3Col', 4=>'Table4Col', 5=>'Table5Col' );
$table_process = array();
foreach($table_names as $table_col_count=>$table_name)
{
$table_process[$table_col_count] = new table_process($con, $table_name);
}
open_file($file_name);
while (!$file_name->eof())
{
$line = explode(" ", trim($file->fgets()));
$table_process[count($line)]->make_row($line);
}
foreach($table_process as $table_process_name)
{
unset($table_process_name);
}
class table_process
{
var $db;
var $row_array = array();
var $field_name_store = '';
var $table_name = '';
var $record_count = 0;
var $update_clause = '';
var $rows_to_process = 255;
function __CONSTRUCT($db, $table_name, $update_clause = '')
{
$this->db = $db;
$this->table_name = $table_name;
$this->update_clause = $update_clause;
}
function __DESTRUCT()
{
if (count($this->row_array) > 0)
{
$this->process_rows();
}
}
function field_names($in_field_names)
{
$this->field_name_store = "(`".implode("`,`", $in_field_names)."`)";
}
function record_count()
{
return count($this->record_count);
}
function make_row($in_row)
{
$ret = true;
foreach($in_row AS &$in_field)
{
$in_field = (($in_field == null) ? "NULL" : "'".$this->db->escape($in_field)."'");
}
$this->record_count++;
$this->row_array[] = "(".implode(",", $in_row).")";
if (count($this->row_array) > $this->rows_to_process)
{
$ret = $this->process_rows();
}
return $ret;
}
function process_rows()
{
$ret = true;
$sql = "INSERT INTO ".$this->table_name." ".$this->field_name_store." VALUES ".implode(",", $this->row_array)." ".$this->update_clause;
if (!$this->db->query($sql))
{
$ret = false;
}
$this->row_array = array();
return $ret;
}
public function set_rows_to_process($rows_to_process)
{
if (is_numeric($rows_to_process) and intval($rows_to_process) > 0)
{
$this->rows_to_process = $rows_to_process;
}
}
}
?>
该类需要一个带有查询方法的数据库类。应该很容易更改它以匹配您正在使用的连接。
答案 3 :(得分:0)
function func($table)
{
open_file($file_name);
$line = explode(" ", trim($file->fgets()));
$values = "'','".implode("','", $line)."'";
$query = "INSERT INTO `{$table}` values ({$values})";
$stmt = $con->query($query);
}
或者代替爆炸然后爆炸,只需替换替换&#34; &#34;在&#39;,&#39;的文件内容中并在正面和背面添加一个额外的&#39;。但是,如果每个内容都有空间,那么爆炸会导致问题。如果您的数据库不喜欢带引号的数字,您可能需要修改为不引用数字。
function func($table)
{
open_file($file_name);
$values = "'','".str_replace(' ', "','", trim($file->fgets()))."'".
$query = "INSERT INTO `{$table}` values ({$values})";
$stmt = $con->query($query);
}