2014-06-22 7 views
1
# I am using a combination of php prepared statements with mysql. I have created stored functions which work fine. I also am creating a temp table. However when I hardcode the last prepared query my result table is sorted correctly but when I try to use prepared bind parameters it doesn't sort correctly. Here is the flow of what is going on # 


    $createTempTable = ' 
    CREATE TEMPORARY TABLE IF NOT EXISTS table2 AS (

    SELECT st.Songs_ID, st.Num_Of_Votes, st.Song_Title, 
      st.Date_Released, st.MusicLink, st.ytVideoID, 
      "               " AS artists, 
      "               " AS genres 
    FROM Songs_Table st 
     INNER JOIN Songs_Genres_Crossover sgc ON sgc.Song_ID = st.Songs_ID 
    INNER JOIN Song_Genres sg ON 
            sgc.Genre_ID = sg.Genre_ID 
            AND sg.Genre_Label = ? 
    WHERE 
     st.Date_Released >= ? && st.Date_Released <= ? 
    ); 
    '; 


    $stmt1 = $mysqli -> prepare("$createTempTable"); 

    $stmt1->bind_param('sss', $genreLabelLowercase, $startTime, $endTime); 

    $stmt1->execute(); 
    $stmt1->close(); 


    //this calls stored function and requires no params 
    $updateTempTable = ' 
    SELECT populateSongIdsWithArtistsAndGenres(); 
    '; 

    $stmt2 = $mysqli -> prepare("$updateTempTable"); 

    $stmt2->execute(); 
    $stmt2->close(); 


    //this is the function that doesn't seem to bind correctly 
    //notice if i hardcode this and do not use ? in it the query is executed fine 
    $getTempTableResult = ' 
    SELECT Songs_ID, Num_Of_Votes, Song_Title, Date_Released, 
      MusicLink, ytVideoID, artists, genres 
    FROM table2 
    ORDER BY ? 
    LIMIT ? , ? ; 
    '; 

    $stmt3 = $mysqli -> prepare("$getTempTableResult"); 

    $topVotedOrderBy = 'Num_Of_Votes DESC, artists ASC, Song_Title ASC'; 
    $firstSong = 0; 
    $songsToUse = 100; 

    $stmt3->bind_param('sii', $topVotedOrderBy, $firstSong, $songsToUse); 

    $stmt3->execute(); 


    /* Bind results */ 
    $stmt3 -> bind_result($songId, $numOfVotes, $songTitle, $dateReleased, 
          $musicLink, $ytVidId, $artists, $genres); 

    while ($stmt3 -> fetch()) { 
    //use results 
    } 

    $stmt3->close(); 

나는 이것이 모든 도움이되기를 바랍니다. stmt3이 올바르게 실행되지 않는 이유를 알아야합니다. 감사! 나는 int mysqli_multi_query를 찾고 있었지만 나는 멀티 쿼리를하기 전에 미리 준비된 명령문으로 보호하는 방식으로 쿼리를 만들고 싶습니다.

Thanks guys I am using the query in this way as a workaround. It is messier but it works fine    # 



$createTempTable = ' 
CREATE TEMPORARY TABLE IF NOT EXISTS table2 AS (

SELECT st.Songs_ID, st.Num_Of_Votes, st.Song_Title, 
     st.Date_Released, st.MusicLink, st.ytVideoID, "               " AS artists, 
     "               " AS genres 
      FROM Songs_Table st 
      INNER JOIN Songs_Genres_Crossover sgc 
      ON sgc.Song_ID = st.Songs_ID 
      INNER JOIN Song_Genres sg 
      ON sgc.Genre_ID = sg.Genre_ID AND sg.Genre_Label = ? 

      WHERE 
      st.Date_Released >= ? && st.Date_Released <= ? 


); 

'; 

$stmt1 = $mysqli -> prepare("$createTempTable"); 

$stmt1->bind_param('sss', $genreLabelLowercase, $startTime, $endTime); 

$stmt1->execute(); 
$stmt1->close(); 



$updateTempTable = ' 
SELECT populateSongIdsWithArtistsAndGenres(); 
'; 

$stmt2 = $mysqli -> prepare("$updateTempTable"); 

$stmt2->execute(); 
$stmt2->close(); 



if($sort === 'Date Released(Newest First)') { 
    //newest released 
    $dateReleasedNewestFirstOrderBy = 'Date_Released DESC, artists ASC, Song_Title ASC'; 
    $getTempTableResult = ' 
SELECT Songs_ID, Num_Of_Votes, Song_Title, Date_Released, MusicLink, ytVideoID, artists, genres FROM table2 ORDER BY '.$dateReleasedNewestFirstOrderBy.' LIMIT '.$firstSong.' , '.$songsToUse.' ; 
'; 
} 
else if ($sort == 'Artist(A-Z)') {//all artists a to z 
    //artist a-z 
    $artistAToZOrderBy = 'artists ASC, Song_Title ASC'; 
    $getTempTableResult = ' 
SELECT Songs_ID, Num_Of_Votes, Song_Title, Date_Released, MusicLink, ytVideoID, artists, genres FROM table2 ORDER BY '.$artistAToZOrderBy.' LIMIT '.$firstSong.' , '.$songsToUse.' ; 
'; 
} 
else if ($sort == 'Title(A-Z)') { 
    //title a-z 
    $songTitlesAToZOrderBy = 'Song_Title ASC, artists ASC'; 
    $getTempTableResult = ' 
SELECT Songs_ID, Num_Of_Votes, Song_Title, Date_Released, MusicLink, ytVideoID, artists, genres FROM table2 ORDER BY '.$songTitlesAToZOrderBy.' LIMIT '.$firstSong.' , '.$songsToUse.' ; 
'; 
} 
else { 
    //top voted 
    $topVotedOrderBy = 'Num_Of_Votes DESC, artists ASC, Song_Title ASC'; 
    $getTempTableResult = ' 
SELECT Songs_ID, Num_Of_Votes, Song_Title, Date_Released, MusicLink, ytVideoID, artists, genres FROM table2 ORDER BY '.$topVotedOrderBy.' LIMIT '.$firstSong.' , '.$songsToUse.' ; 
'; 
} 

$stmt3 = $mysqli -> prepare("$getTempTableResult"); 

$stmt3->execute(); 

$stmt3 -> bind_result($songId, $numOfVotes, $songTitle, $dateReleased, $musicLink, $ytVidId, $artists, $genres); 

while ($stmt3 -> fetch()) { 
//use results 
} 
$stmt3->close(); 
+0

가능한 중복 : http://stackoverflow.com/questions/4741845/mysqli-prepare-statements-binding-order-by – bloodyKnuckles

+0

http://ca3.php.net/manual/en/ mysqli.prepare.php "... 테이블이나 컬럼 이름과 같은 식별자에는 사용할 수 없습니다 ..."사용자 입력에서 오는 것이기 때문에 ORDER BY 절에 대해 prepared statement를 사용한다면 look 사용자 입력을 검증하거나 mysqli_real_escape_string을 사용해야한다. – bloodyKnuckles

답변

0

참조 : http://ca3.php.net/manual/en/mysqli.prepare.php

...[prepared statements] are not allowed for identifiers (such as table or 
column names)... 

당신이 주문 후 모습 사용자 입력에 의해 결정 될 것으로 예상하기 때문에, 열 이름을 포함 ORDER BY 절에 대한 준비된 문을 사용하는 경우 사용자 입력을 확인하거나 mysqli_real_escape_string을 사용해야합니다.

: