0

1 つのテーブルにクエリを実行し、その情報を使用して別のテーブルにクエリを実行する必要があります。最後に、最初のテーブルでクエリを実行し、テーブルとクエリの両方の結果を表示する必要があります。

$summary = mysql_result($y,$j, 'WebDesc');逆を除いてすべてが機能$sql3し、正しくエコーされ、クエリを手動で実行すると、WebDesc. 「複数のクエリ」をサポートしていないマニュアルを見ましたが、それmysql_queryが何を意味するのかよくわかりません。最初の 2 つのクエリ ($sqlおよび$sql2) はうまく連携して動作しmysql_queryます。

$sql = "SELECT * FROM T_AdditionalInfo WHERE Description LIKE '" . $page_title . "%'" . " AND (ProductType='FG8' OR ProductType='FG1') AND Active='Yes'";
$x = mysql_query($sql);
$table_data = "";

while ($result = mysql_fetch_array($x)) {
    $kilnnum = $result['ItemNo'];
} //kilnnum should be set to ItemNo of last matching kiln

$sql2 = "SELECT * FROM T_Accessories WHERE KilnNo='$kilnnum'"; 
$x = mysql_query($sql2);
$rows = mysql_num_rows($x);

for ($j = 0 ; $j < 4 ; ++$j) //increment through 0-3 first 4 rows of data
{
    $item_no = mysql_result($x,$j, 'PartNo'); //get PartNo from T_Accessories
    $sql3 = "SELECT ItemNo,WebDesc FROM T_AdditionalInfo WHERE ItemNo='$item_no'"; //Pull data from T_AdditionalInfo for above PartNo/ItemNo
    $y = mysql_query($sql3);

    $title_w_spaces = mysql_result($x,$j, 'Description'); //Still pulling title from T_Accessories to match image names
    $title = str_replace(" ", "-", $title_w_spaces); //Still using title for heading from T_Accessories
    $summary = mysql_result($y,$j, 'WebDesc'); //Pulling description from T_AdditionalInfo
    if ($title <> "") {
    $table_data .= "
        <div>
            <h6> $title_w_spaces </h6>
            <img src='/images/" . $title . ".jpg' alt='" . $title ."' title='" . $title . "' class='alignnone size-full' width='114' />
            <p>" . $summary . "</p>  
        </div>";
        } //end if
} //end for
4

1 に答える 1

0

他の人が示唆しているように、複数の選択を単一のJOINステートメントに結合することもお勧めします。他の人も言っているように、mysqliまたはPDOを使用することをお勧めします。これらは両方とも、SQL インジェクションを効果的に排除するだけでなくdeprecated、次のリリースで削除されるコードを使用できないようにするのにも役立ちます。

クエリとループ ロジックを書き直す方法の例を次に示します (mysqli を使用してからしばらく経っているため、例では PDO を使用しています)。テーブル間の関連付けが 100% わからないため、結合の一部を見逃している可能性があります。

$sql = "
SELECT 
    Description, 
    WebDesc 
FROM T_AdditionalInfo info JOIN T_Accessories acc ON info.ItemNo = acc.PartNo
WHERE info.Description LIKE :title
";
$db = false;
$table_date = '';
try {
    $db = new PDO(...);
}
catch(PDOException $e) {
    $db = false
    //Failed to connect to DB for some reason
}
if($db !== false) { //Did we connect?
    if(($stmt = $db->prepare($sql)) !== false) {  //Prepare the statement
        $stmt->bindParam(':title', '%abc%');  //Bind the parameter
        if($stmt->execute() !== false) {  //Execute the statement
            while($row = $stmt->fetch(PDO::FETCH_ASSOC)) { //Loop through the result set
                $table_w_spaces = $row['Description']; //Get title
                $title = str_replace(' ', '-', $title_w_spaces); //alter title
                $table_date .= "
<div>
  <h6>{$table_w_spaces}</h6>
  <img src="/images/{$title}.jpg" alt="{$title}" title="{$title}" class="alignnone size-full" width="114" />
<p>{$row['WebDesc']}</p>
</div>
";
            }
        }
        else {
            //Execution of statement failed
            print_r($stmt->errorInfo());
        }
    }
    else {
        //An error occurred when preparing SQL statement, probably a SQL error
        print_r($stmt->errorInfo());
    }
}

これは私が少し先を行っているかもしれませんが、おそらくあなたはこのようなことをたくさんやっていると思います. PDO や mysqli に慣れてきたら、クラスを作成して多くの反復作業をなくすとよいでしょう。また、別の DB サーバー (MySql から PostGre、または MSSQL へ) に変更したり、サーバー名を変更したりする必要がある場合でも、1 つの場所で問題なく変更できます。以下のクラスの例が最初は少し混乱しているように見えても、心配しないでください。以下の例を参照してください。明確になるはずです。executeQueryこれは基本的に、反復的なタスクをすべて取り除き、それらを 2 つの特定の機能に統合する方法ですexecuteNonQuery

class Database {
    private $db = false;
    private $connected = false;
    public function __construct($db = 'DefaultDBName', $username = 'MyUser', $password = 'MyPassword') {
        $this->connect($db, $username, $password); //Auto connect when you create a new database
    }
    /**
     * Connect to a database
     * 
     * @param $db The database to connect to; default is DefaultDBName
     * @param $username The username to connect as; default is MyUser
     * @param $password The password to use when connecting; default is MyPassword
     * @return True/False if the connection was successfull
     */
    public function connect($db = 'DefaultDBName', $username = 'MyUser', $password = 'MyPassword') {
        try {
            $this->db = new PDO('drivername:Server=MYDBSERVER;Database=' . $db, $username, $password); //Create new connection
            $this->connected = true; //We are connected
        }
        catch(PDOException $e) { //Oh no.  An error
            $this->db = false; //Set DB back to false, just in case
            $this->connected = false; //We couldn't connect
            //You can do something with the error message if you wish
        }
        return $this->connected
    }
    /**
     * Prepares a SQL statement for execution
     * 
     * @param $sql The SQL string to be prepared
     * @params $params An optional array of parameters to bind to the statement
     * @return The prepared statement; false if failed
     */
    public function prepare($sql, $params = array()) {
        $stmt = false;
        if($this->connected) { //Are we connected
            if(($stmt = $this->db->prepare($sql)) !== false) { //Prepare the statement
                foreach($params as $param => $value) { //Bind the parameters
                    $stmt->bindValue($param, $value);
                }
            }
            else {
                //You can do something with $stmt->errorInfo();
            }
        }
        return $stmt;
    }
    /**
     * Execute a prepared statement
     * 
     * @param $stmt A PDO statement
     * @param $params An optional array of parameter values
     * @return True/False
     */
    public function execute($stmt, $params = array()) {
        if($this->connected) { //Are we connected
            if(!empty($params)) { //Can't bind an empty array of parameters
                $result = $stmt->execute($params); //Execute with parameters
            }
            else {
                $result = $stmt->execute(); //Execute without parameters
            }
        }
        return $result;
    }
    /**
     * Gets the results from an executed statement
     * 
     * @param $stmt A reference to a PDO statement
     * @return An array of results from the statement
     */
    public function getResults($stmt) {
        $results = array();
        if($stmt !== false) { //Make sure we have a valid statement
            while($row = $stmt->fetch(PDO::FETCH_ASSOC))) { //Get all of the data for the row
                $results[] = $row; //Add the row to the results array
            }
        }
        return $results; //Return the results
    }
    /**
     * Executes a query and returns the results
     * 
     * @param $sql The SQL query
     * @param $parameters An array of parameters
     * @return An array of results or false if execution failed
     */
    public function executeQuery($sql, $params = array()) {
        $results = false;
        if($this->connected) { //Are we connected
            if(($stmt = $this->prepare($sql, $params)) !== false) { //Prepare the statement
                if($this->execute($stmt) !== false) { //Execute the statement
                    $results = $this->getResults($stmt); //Get the result set
                }
            }
        }
        return $results;
    }
    /**
     * Executes a query, but returns no results
     * 
     * @param $sql The SQL query
     * @param $parameters An optional array of paraters
     * @return True/False
     */
    public function executeNonQuery($sql, $params = array()) {
        $success = false;
        if($this->connected) { //Are we connected
            if(($stmt = $this->prepare($sql, $params)) !== false) { //Prepare the statement
                if($this->execute($stmt) !== false) { //Execute the statement
                    $success = true; //Successfully executed
                }
            }
        }
        return $success;
    }
}

各例では、次のことを前提としています。

$sql = "
SELECT 
    Description, 
    WebDesc 
FROM T_AdditionalInfo info JOIN T_Accessories acc ON info.ItemNo = acc.PartNo
WHERE info.Description LIKE :title
";
$parameters = array(':title' => '%abc%');

1) 新しいデータベース クラスを使用してすべてをまとめる

$db = new Database();
if(($stmt = $db->prepare($sql, $parameters)) !== false) {
    if($db->execute($stmt)) {
        $results = $db->getResults($stmt);
        foreach($results as $result) {
            //Do something with this result
        }
    }
}

preparing2) これで、このクラスを作成すると、ステートメント、bindingパラメーター、executingステートメント、そしてretrieving結果セットの反復性がすべて取り除かれ、すべてが簡単になると言ったことがわかりました。以下は、上記のすべてを 1 行で実行する方法の簡単な例です。

$db = new Database();
if(($results = $db->executeQuery($sql, $parameters)) !== false) {
    foreach($results as $result) {
        //Do something with this result
    }
}

3) しかし、結果セットを返さないクエリを使用したい場合はどうすればよいでしょうか? 混乱することなくステートメントをすばやく実行できますか? はい。機能を使用できますexecuteNonQuery。以下はその一例です。

$db = new Database();
$sql = 'update table1 set field = :value where id = :id';
$parameters = array(':value' => 'val1', ':id' => '5');
if($db->executeNonQuery($sql, $parameters)) {
    //Yay!  The update was successfull
}

アップデート

OPとの会話(コメントを参照)によると、ここに彼のクエリの更新バージョンがあり、望ましい結果が得られるはずです。LIMIT 1クエリの一部により、 ItemNo32 個すべて (8 個のアクセサリ X 4 個の ItemNo) ではなく、8 個のアクセサリのみを検索する必要がある 1 つだけが使用されることが保証されます。

SELECT 
    info.Description, 
    acc.WebDesc 
FROM T_AdditionalInfo info JOIN T_Accessories acc ON info.ItemNo = acc.PartNo 
WHERE info.ItemNo = (SELECT ItemNo FROM T_AdditionalInfo WHERE Description LIKE %abc% LIMIT 1)

ネストされた select ステートメントは a と呼ばsubquery. ます。サブクエリは、SQL でこのようなことや句を使用する場合に非常に役立ちます。INSELECT * FROM t1 WHERE id IN (SELECT t1_id FROM t2)

于 2013-06-21T18:19:05.580 に答える