PHP/SQLSRV:3个查询问题

PHP/SQLSRV:3个查询问题,php,sql,database,unicode,sqlsrv,Php,Sql,Database,Unicode,Sqlsrv,我正在Windows 7上运行带有PHP5.3和SQL Server 2014的IIS 6.1。我的数据库基于我的iTunes播放列表。我目前正在使用的脚本从表单接收乐队名称,然后返回一个表格,其中包含该乐队的每个专辑,显示每个专辑的名称和年份,然后是该专辑中每首歌曲的曲目号、名称和长度。它在我的大多数专辑中都能正常工作,但有三个问题: 非拉丁字符不会出现。我有几种不同语言的音乐,我可以在SQL Server中使用Unicode字符进行查询,但是当我尝试在web上返回这些结果时,所有非拉丁字符都

我正在Windows 7上运行带有PHP5.3和SQL Server 2014的IIS 6.1。我的数据库基于我的iTunes播放列表。我目前正在使用的脚本从表单接收乐队名称,然后返回一个表格,其中包含该乐队的每个专辑,显示每个专辑的名称和年份,然后是该专辑中每首歌曲的曲目号、名称和长度。它在我的大多数专辑中都能正常工作,但有三个问题:

  • 非拉丁字符不会出现。我有几种不同语言的音乐,我可以在SQL Server中使用Unicode字符进行查询,但是当我尝试在web上返回这些结果时,所有非拉丁字符都显示为问号。我看到的这个问题的答案并没有解决我的问题(例如,添加一个标题和meta标记以将页面设置为UTF-8)

  • 一张特别的专辑(深红国王的《云雀的舌头在肉冻里》)把这个问题搞糟了,大概是因为专辑标题中只有一句话。奇怪的是,专辑的标题显示得很好,但不是那张专辑上的曲目。名称中带有单引号的其他歌曲和专辑不会引起问题,仅此特定专辑/歌曲。我尝试了所有我能想到的转义单引号的组合,它们都会导致查询更难失败。我打开和关闭了魔法引号,但没有结果。如下所述,查询返回此错误:

    Array ( [0] => Array ( [0] => 42000 [SQLSTATE] => 42000 [1] => 102 
    [code] => 102 [2] =>         [Microsoft][SQL Server Native Client 11.0]
    [SQL Server]Incorrect syntax near 'Tongues'. [message] => [Microsoft]
    [SQL Server Native Client 11.0][SQL Server]Incorrect syntax near 'Tongues'. ) 
    [1] => Array ( [0] => 42000 [SQLSTATE] => 42000 [1] => 105 [code] => 105 
    [2] => [Microsoft][SQL Server Native Client 11.0][SQL Server]
    Unclosed quotation mark after the character string ' ORDER BY TrackNumber'.    
    [message] => [Microsoft][SQL Server Native Client 11.0][SQL Server]
    Unclosed quotation mark after the character string ' ORDER BY TrackNumber'. ) )
    
  • 我不知道如何在查询中包含通配符。例如,如果我搜索“艾莉森·克劳斯”,我只会得到艾莉森本人的结果。如果我想搜索Alison是多个艺人之一的歌曲(例如,Alison Krauss&Union Station),我需要在查询中添加通配符,但我不知道如何执行,要么将其添加到传递到查询中的变量中,要么在查询本身中

  • 代码如下:

        header('Content-type: text/html; charset=UTF-8');
    
        require_once ('connect.php');
    
        echo '<table align = center cellpadding = 2 cellspacing = 2>';
    
        $band = stripslashes($_REQUEST['band']);
    
        $albumqry = "SELECT AlbumName, AlbumYear FROM vw_AlbumTracks WHERE ArtistName LIKE '$band'         
        GROUP BY AlbumName, AlbumYear ORDER BY AlbumYear";
    
        $ayqry = SQLSRV_QUERY($conn, $albumqry);
        if( $ayqry === false )
        {
             echo "Error in executing query.</br>";
             die( print_r( sqlsrv_errors(), true));
        }
    
        while ($record = SQLSRV_FETCH_ARRAY ($ayqry)) {
    
        $album = $record['AlbumName'];
    
        echo '<tr><td colspan=3><b>' . $album . ' (' . $record['AlbumYear'] . ')</b></td></tr>';
    
        $query = "SELECT TrackNumber, SongName, SongLength FROM vw_AlbumTracks WHERE ArtistName                 
        LIKE N'$band' AND AlbumName LIKE N'$album' ORDER BY TrackNumber";
    
        $stmt = sqlsrv_query( $conn, $query);
        if( $stmt === false )
        {
             echo "Error in executing query.</br>";
             die( print_r( sqlsrv_errors(), true));
        }
    
        while( $track = sqlsrv_fetch_array( $stmt, SQLSRV_FETCH_ASSOC) ) {
        echo '<tr><td width = 5>' . $track['TrackNumber'] . '.</td>
        <td width = 300>' . $track[stripslashes('SongName')] . '</td>
        <td style="text-align:right">' . $track['SongLength'] . '</right></td></tr>';
    
        }
    
        echo '<tr></tr>';
    
        }
    
        echo '</table>';
    
    header('Content-type:text/html;charset=UTF-8');
    需要一次_('connect.php');
    回声';
    $band=stripslashes($_请求['band']);
    $albumqry=“从vw\U AlbumTracks中选择AlbumName、AlbumYear,其中艺人名称如“$band”
    按相册名称分组,按相册年排序”;
    $ayqry=SQLSRV_查询($conn,$albumqry);
    如果($ayqry==false)
    {
    echo“执行查询时出错。
    ”; 模具(打印错误(sqlsrv_errors(),true)); } 而($record=SQLSRV\u FETCH\u数组($ayqry)){ $album=$record['AlbumName']; 回音“.$album.”(“.$record['AlbumYear].”); $query=“从vw\U AlbumTracks中选择曲目号、歌曲名、歌曲长度,其中ArtistName 像N'$band'和AlbumName像N'$album'按曲目编号排序”; $stmt=sqlsrv_查询($conn,$query); 如果($stmt==false) { echo“执行查询时出错。
    ”; 模具(打印错误(sqlsrv_errors(),true)); } 而($track=sqlsrv\u fetch\u数组($stmt,sqlsrv\u fetch\u ASSOC)){ 回显'.$track['TrackNumber'].'。 “.$track[stripslashes('SongName')]” “.$track['SongLength']”; } 回声'; } 回声';
    解决了我自己的两个问题

  • 添加通配符:将通配符和N(用于输入Unicode字符)添加到变量定义中。例如:

    $band = "N'" . stripslashes($_POST['band']) . "%'";
    $albumqry = "SELECT AlbumName, AlbumYear FROM vw_AlbumTracks WHERE ArtistName 
    LIKE $band GROUP BY AlbumName, AlbumYear ORDER BY AlbumYear";
    
  • 转义传递到SQL查询的PHP中的单引号:使用str_replace和addslashes首先转义麻烦的单引号,然后以SQL理解的方式重新转义

    $album = "N'" . str_replace("\'", "''", addslashes($record['AlbumName'])) . "'";
    
  • 不过,在Unicode方面仍然完全迷失了方向。我加了echo$band;到页面,并在输入윤하 对于上一页上的表单,它显示N'윤하%', 这正是它应该传递给SQL Server的内容,但SQL Server Profiler中的跟踪将查询显示为

        SELECT AlbumName, AlbumYear FROM vw_AlbumTracks 
        WHERE ArtistName LIKE N'윤하%' 
        GROUP BY AlbumName, AlbumYear ORDER BY AlbumYear
    
    因此,不知何故,Unicode在从PHP到SQL Server的过程中变得乱七八糟,这两者都能够自己正确地显示它