2017-05-26 73 views
0

我在數據庫中有4個表,並且在所有表中都有一個獨特的clientid,但是其餘字段是不同的。如果我們搜索任何客戶端ID,我們如何從任何表中獲取與搜索到的客戶端ID相對應的信息。從mysql的多個表中選擇數據?

$clientid=$_POST['client']; 
$query = "SELECT * FROM 'pfs' 
      JOIN 'pfssurety' 
      JOIN 'iso' 
      JOIN 'incometax' 
      WHERE clientid='$clientid'"; 
$result = mysql_query($query)or die (mysql_error()); 

while($row=mysql_fetch_array($result)) { 
    echo $row['clientid']; 
    echo $row['name']; 
} 
+0

開始你錯過了'on'子句 – Jens

+1

**使用不推薦使用的'mysql_ *'API停止**。使用'mysqli_ *'或'PDO' – Jens

+1

這不會起作用當你使用JOIN時,你需要使用ON子句 和mysql_query,mysql_fetch_array()將不起作用,你需要使用mysqli _.... –

回答

0

你打算使用backtique而不是單引號。否則,你的表名被認爲是普通的字符串文字。此外,你缺少你所有JOIN條款ON條件,使您的查詢

SELECT * FROM 'pfs' 

實際上應該是

SELECT * FROM `pfs` 

更改您的查詢是

SELECT * FROM `pfs` 
JOIN `pfssurety` ON condition 
JOIN `iso` ON condition 
JOIN `incometax` ON condition 
WHERE clientid='$clientid' 
0

你是在正確的軌道上使用JOIN。您需要指定JOIN應該在的公共列。

https://www.w3schools.com/sql/sql_join_left.asp

SELECT a.fieldname, i.fieldname, t.fieldname, p.fieldname FROM 'pfs' as a 
LEFT JOIN 'pfssurety' as p ON p.clientid = a.clientid 
LEFT JOIN 'iso' as i ON i.clientid = a.clientid 
LFT JOIN 'incometax' as t ON t.clientid = a.clientid 
WHERE a.clientid='$clientid'"; 

此外,你應該逃避你的變量,以防止SQL注入。在最低限度:

a.clientid= "' . mysqli_real_escape_string($clientid) . '"'; 

http://php.net/manual/en/mysqli.real-escape-string.php

+0

爲什麼你圖片左加入,他可能想要nulls https://stackoverflow.com/questions/38549/what-is-the-difference-between-inner-join-and-outer-join –

+0

已添加註射單線程,我發誓每個sql問題都有未轉義的變量。 – Blueline

+0

關於加入好點。對於大多數加入者來說,加入是一種習慣。 – Blueline

0

也許你需要在設置你的加入爲這樣的事情:

SELECT * FROM 'pfs' 
JOIN 'pfssurety' ON pfs.clientid=pfssurety.clientid 
JOIN 'iso' ON pfs.clientid=iso.clientid 
JOIN 'incometax' ON pfs.clientid=incometax.clientid 
WHERE clientid='$clientid' 

Ÿsuposed所有表具有客戶端ID屬性。

  • 而不是使用SELECT *您可以使用您需要
+0

此代碼容易受到SQL注入 –

0

您的代碼很容易受到SQL注入不同屬性的枚舉,你永遠不應該直接使用用戶輸入到SQL查詢。在你的代碼的問題是在這裏:

$clientid = $_POST['client']; // anyone could manipulate this field to inject malicious code 
# ... 
WHERE clientid='$clientid'"; 

檢查了$ _POST值[ '客戶']是發生了什麼:'或1 = 1;

接下來,如其中一條評論中提到的停止使用已棄用的方法,而是例如您可以使用mysqli。下面是如何使用mysqli的預處理語句,以避免SQL注入一個例子:

$conn = new mysqli($servername, $username, $password, $dbname); 
// Check connection 
if ($conn->connect_error) { 
    die("Connection failed: " . $conn->connect_error); 
} 

$stmt = $conn->prepare('SELECT * FROM `pfs` JOIN `pfssurety` ON condition JOIN `iso` ON condition JOIN `incometax` ON condition WHERE clientid = ?'); 

$stmt->bind_param('i', $clientid); 
$stmt->execute(); 
$stmt->close(); 
$conn->close(); 

已準備語句是用於以高效率重複執行相同(或相似)的SQL語句的功能。

相比於直接執行SQL語句,預處理語句主要有三個優點:

  • 預處理語句大大減少了分析時間,對查詢準備做一次(但語句執行多次)

  • 綁定參數減少帶寬的服務器,因爲你需要每次只傳送參數,而不是整個查詢

  • 準備語句的對於SQL注入非常有用,因爲稍後使用不同協議傳輸的參數值無需正確轉義。如果原始語句模板不是從外部輸入派生的,則SQL注入不會發生。

最後一兩件事值得一提,儘量不要使用*獲取所有列,而不是簡單地列出你需要得到的列。即使您需要獲取所有列,爲什麼不使用*也有很好的理由,而是列出所有列。

+0

你缺少'$ clm.tm'在'$ stmt-> bind_param('i',$ clientid);''和'$ stmt-> execute();' –

1

下面是使用的mysqli的實現,並防止注射您$clientid其中ID是一個數字,然後篦零AUTO_INCREMENT列將永遠不會有一個0值,他們在1

// as this is an int using inval will force it to be a valid whole number 
// basic SQL Injection Protection for a fixed id 

$clientid = intval($_POST['client']); 
if($clientid === 0){ 
    // it was not a valid number as an auto_increment field in mysql can never be 0 
    die("invalid client"); 
} 

$query="SELECT * FROM `pfs` 
    JOIN `pfssurety` ON pfssurety.clientid = pfs.clientid 
    JOIN `iso` ON iso.clientid = pfs.clientid 
    JOIN `incometax` ON incometax.clientid = pfs.clientid 
    WHERE pfs.clientid=$clientid"; 

$result= mysqi_query($query) or die("Query Failed"); 

while($row=mysql_fetch_array($result)) 
{ 
    echo $row['clientid']; 
    echo $row['name']; 
} 
+0

之間這是怎麼回事阻止SQL注入?您仍將用戶輸入直接用於查詢,您應該使用預準備語句。 – lloiacono

+0

no im not'$ clientid = intval($ _ POST ['client']);'intval會將它變成一個int,無論如何,如果它有任何沒有數字的字符,它會導致'0'去學習php ... –

+0

我錯過了intval()部分,抱歉。國際海事組織,你應該使用準備好的聲明,因爲這是你想要使用它們的主要原因之一,在這裏閱讀更多關於它們:https://www.w3schools.com/php/php_mysql_prepared_statements.asp – lloiacono