2014-07-14 44 views
2

我有一個特殊的MSSQL語句,用於檢索已存在的指定行的標識或INSERT,然後檢索該標識。此SQL似乎在SQL Management Studio以及我的幾個.NET C#應用程序中工作得很好。如何在PHP中使用Microsoft SQL Driver選擇SCOPE_IDENTITY()?

不幸的是,我被要求使用PHP來完成這個特定任務,並且我很難嘗試使用PHP和官方的Microsoft SQL驅動程序。

該語句在INSERT後沒有返回ID(或者如果是,我無法檢索它)。有人可以看看我在哪裏,如果我錯了嗎?

我在Microsoft SQL Driver 3.0中使用PHP 5.3.23。這裏是我的代碼:

$sql = '' 
     . 'IF (SELECT COUNT(*) FROM users WHERE sAMAccountName = ?) = 0 ' 
     . 'BEGIN ' 
     . 'INSERT INTO users (role, sAMAccountName, fullName) ' 
     . 'VALUES (1, ?, ?) ' 
     . 'SELECT SCOPE_IDENTITY() ' 
     . 'END ' 
     . 'ELSE SELECT id FROM users WHERE sAMAccountName = ?'; 
$params = array($requester, $requester, $fullName, $requester); 
$query = $this->SqlQuery($sql, $params); 

function SqlQuery($sql, array $params) { 
    $conn = $this->SqlConnection(null, null, null, null); // x4 null = use default connection options 
    $query = sqlsrv_query($conn, $sql, $params); 
    if ($query) { 
     sqlsrv_fetch($query); 
     echo 'Result: ' . sqlsrv_get_field($query, 0); // This should return an ID regardless 
     sqlsrv_close($conn); 
    } 
} 

下面是結果HTML(無結果):

Result: 
+0

我對T-SQL不是很熟悉,所以如果我提出廢話,請耐心等待,但......是完整的自包含代碼嗎?這都是一條線,例如沒有分隔符。 INSERT和SELECT。看起來很奇怪它可以運行: - ? –

+0

@ÁlvaroG.Vicario行中唯一依賴行的是行註釋('--')。除了包括多個語句的SQL(和T-SQL)中的所有內容,都可以在沒有任何換行符的情況下編寫。傳統上,語句分隔符(';')並不是必需的,儘管它們是新語句關鍵字('WITH','RECEIVE',..)所必需的,並且將來將需要它們。 – RBarryYoung

+0

@RBarryYoung - 謝謝你的指針。 –

回答

1

您在查詢的開始需要一個SET NOCOUNT ON;

您的INSERT語句實際上會返回某些內容:空記錄集加上消息「(1 row affected)」。 SSMS只是連接所有記錄集,但在sqlsrv中,您必須明確地前進到第二個記錄集以查看您的SCOPE_IDENTITY()結果。通過關閉rowcount功能,無用的結果集將被廢除,並且它會按照您的要求進行操作。

+0

有用的知道,並會解釋爲什麼我的聲明似乎在SSMS和甚至在C#應用程序中工作。即使沒有SET NOCOUNT ON;如果我使用sqlsrv_next_result($ query)前進到下一個記錄集,我仍然應該看到SELECT SCOPE_IDENTITY()的結果。 sqlsrv_fetch($查詢); $ id = sqlsrv_get_field($ query,0);'?我幾乎肯定我嘗試過,而我所得到的只是「假」。 – Robula

+0

所以你試過'SET NOCOUNT ON',它解決了你的問題嗎? –

2

不知道這是一個選擇,但我會改變SQL語句轉換成一個存儲過程,幷包括身份的歸還。一旦存儲過程進行這些更改的說法

'SELECT SCOPE_IDENTITY() ' 

'SELECT SCOPE_IDENTITY() as id' 

然後在PHP,你應該能夠訪問ID作爲數據表。存儲過程會將數據作爲數據表返回,不確定在PHP端,我是一個.NET人

如果您需要將語句轉換爲存儲過程的幫助,請告訴我。

編輯:
假設sAMAccountName是此表上的主鍵,並且您在您的問題中聲明您不能在INSERT過程中返回身份。然後,將SQL更改爲此將爲您解決問題。

$sql = '' 
    . 'IF (SELECT COUNT(*) FROM users WHERE sAMAccountName = ?) = 0 ' 
    . 'BEGIN ' 
    . 'INSERT INTO users (role, sAMAccountName, fullName) ' 
    . 'VALUES (1, ?, ?) ' 
    . 'END ' 
    . 'SELECT id FROM users WHERE sAMAccountName = ?'; 
+0

存儲過程對我來說不是一個真正的選擇。我不得不在另一個連接中激發一個完全獨立的SQL查詢,如果我不能得到這個工作。謝謝 – Robula

+0

在我看來,由於您在不同的應用程序的多個位置執行此操作,存儲過程是唯一真正有意義的事情。希望你永遠不需要改變它,因爲你現在在幾個應用程序中擁有相同的代碼。 –

+1

在上面的答案中更改了方法。 – Dbloch

1

你可以試試看。剝去額外的單引號和連接並應用Dbloch的建議。

$sql = 'IF (SELECT COUNT(*) FROM users WHERE sAMAccountName = ?) = 0 
      BEGIN 
      INSERT INTO users (role, sAMAccountName, fullName) 
      VALUES (1, ?, ?) 
      SELECT SCOPE_IDENTITY() as id 
      END 
      ELSE SELECT id FROM users WHERE sAMAccountName = ?'; 
+0

謝謝,但我無法得到這個爲我工作。 – Robula

+0

+1很難相信SQL Server Management Studio能夠完美地運行這樣的單線程。我確定發佈的代碼實際上缺少分隔符,無論是回車還是分號。 –

+0

必須是,我在SSMS自己測試它,它完美的工作。 – VikingBlooded

相關問題