2014-10-27 87 views
0

有沒有一種方法來使用PHP動態插入功能?多個INSERT INTO查詢

我有一個函數處理幾個文件,它們遵循相同的結構,但並不總是具有相同數量的值。例如,如果一個文件有10個值,它將寫入某個表,如果它有3個,它將寫入另一個表。

我曾經想過一個開關塊,東西就這個僞代碼行:

但是此塊僅與硬編碼的情況下交易。我想知道是否有辦法操縱查詢,並設置爲適應從文件中讀取的值的數量並指定寫入適當的表格?

編輯:我設法開發了我想要的動態系統,有可能追加我想要的字符串值然後運行字符串。我稍微改了一些代碼(只有處理這個主題的部分在這裏),所以如果複製和粘貼它不應該工作,但是我知道我是如何做到的。歡呼的答案。

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

什麼是表格結構和你得到的值? – 2014-10-27 10:58:45

+0

您必須指定哪些「列」包含在特定值中。然後你可以用動態列和動態值填充查詢。 – Adimeus 2014-10-27 10:59:23

+0

將會有幾個表格,每個表格都有多個值。該表在被調用函數之前是已知的,我仍然沒有編碼,我只是在探索這些選項。 我想我明白你的意思@Adimeus。 – Comum 2014-10-27 11:04:40

回答

0

可能的解決方法。

這使用一個數組存儲每個列數的表名稱。

它也使用一個類一次插入多行(在一個插入語句中插入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; 
     } 
    } 
} 

?> 

該類需要一個帶查詢方法的數據庫類。您應該很容易將其更改爲與您正在使用的連接相匹配。

+0

我會研究你的代碼,並試着理解它的邏輯。主要是因爲我的代碼缺乏效率(如你所建議的),我需要提高傳輸速度。乾杯。 – Comum 2014-10-27 13:23:05

0

這聽起來像你想的各種INSERT語句中,可以自動識別從輸入文件中提供的數據項(和數據項的可能的類型)的數量使用哪個表。

您的問題的答案:不,SQL不這樣做。

從你的問題,你很好地創建一個客戶端程序,這是特定於你的應用程序,將做你想做的。編寫自己的程序是一種正確的方法:您可以在知道應用程序細節的情況下控制表選擇邏輯和錯誤處理。

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 ['products']);,你會得到如下內容:

array(
    0 => array(
     'id' => '...', 
     'type' => '...', 
    ), 
    1 => array(
     'id' => '...', 
     'type' => '...', 
    ) 
) 

這使您可以執行插入onc的邏輯e,然後用一個循環來完成所有的字段。

的(僞)代碼將是這樣的:

$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 
     } 
    } 
} 
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); 
} 

或代替爆炸然後爆的,只需更換更換「」與文件內容「」並增加了前,後附加」。但是,如果每個內容都有空間,爆炸將導致問題。如果您的數據庫不喜歡帶引號的數字,則可能需要修改爲不引用數字。

function func($table) 
{ 
    open_file($file_name); 
    $values = "'','".str_replace(' ', "','", trim($file->fgets()))."'". 

    $query = "INSERT INTO `{$table}` values ({$values})"; 

    $stmt = $con->query($query); 
}