2013-05-24 16 views
9

Tôi đang trong quá trình chuyển đổi một số trang PHP cũ để sử dụng PDO."Kết quả hoạt động không chứa trường" bằng PDO với MS SQL

Dưới đây là hai câu hỏi đơn giản (không truy vấn thực tế của tôi) để hỗ trợ sự hiểu biết về các vấn đề tôi đang gặp ...

SELECT afield INTO #temptable FROM atable WHERE anotherfield = 'somevalue'; 

SELECT afield,anotherfield,onemorefield FROM atable 
WHERE afield NOT IN (SELECT * FROM #temptable); 

Các truy vấn trên ném lỗi được mô tả trong tiêu đề (hoàn toàn hơn nó ném "Fatal error: của router 'PDOException' với thông điệp 'SQLSTATE [IMSSP]: kết quả hoạt động cho các truy vấn không chứa các lĩnh vực.'")

Nếu tôi thay đổi các truy vấn như thế này ...

with (SELECT afield INTO #temptable FROM atable 
WHERE anotherfield = 'somevalue') AS temptable; 

SELECT afield,anotherfield,onemorefield FROM atable 
where afield NOT IN (SELECT * FROM temptable); 

Điều này dường như có được xung quanh lỗi, nhưng phiên bản này của truy vấn là khủng khiếp khủng khiếp không hiệu quả bởi vì nó xuất hiện để chạy truy vấn hấp dẫn cho mỗi so sánh trường duy nhất trong truy vấn khác.

Có cách nào để tạo biểu mẫu đầu tiên (tạo bảng tạm thời một lần) hoạt động với PDO không?

Nó hoạt động tốt trên trang cũ sử dụng mssql.

EDIT: Tôi biết tôi có thể làm điều này theo cách 'lộn xộn' bằng cách tạo bảng thực, chạy nó trong php, sau đó chạy truy vấn thứ hai (trong cuộc gọi php riêng), sau đó chạy truy vấn thứ ba để thả bảng đầu tiên. Nhưng tôi không muốn phải nghỉ mát đến điều đó! :)

+0

Lưu ý rằng các từ khóa SQL như 'SELECT, WHERE, FROM ...' nên được viết hoa. Điều này sẽ cải thiện khả năng đọc. Bạn nên bắt đầu với điều này – hek2mgl

+0

đầu tiên Nếu bạn nhấn mạnh! . – MrVimes

+0

Bạn có thực sự tách các truy vấn bằng dấu chấm phẩy ';' không? – hek2mgl

Trả lời

10

Công cụ PDO nhìn thấy truy vấn này khi trả về hai tập kết quả (công cụ mssql cũ hơn có lẽ chỉ bỏ qua tất cả trừ truy vấn cuối cùng trong chuỗi truy vấn tổng thể). Tôi đã cố gắng để làm cho nó hoạt động bằng cách bỏ qua các tập kết quả đầu tiên (bảng tạm thời) bằng cách sử dụng lệnh sau

$statement->nextRowset(); 

Và sau đó sử dụng $statement->fetch(); như bình thường

31

Nếu bạn đang sử dụng một thủ tục lưu trữ sau đó sử dụng

SET NOCOUNT ON 

Vấn đề là thủ tục được lưu trữ trả về kết quả chứa số hàng bị ảnh hưởng như kết quả đầu tiên.

Microsoft Documentation

1

Tôi đang sử dụng laravel5 và đây là cách tôi cố định vấn đề này;

DB::select("SET ANSI_NULLS ON; SET ANSI_WARNINGS ON;EXEC [storedprocedure] $param1,$param2;"); 
+1

Cảm ơn Kamaro. Tôi cũng đang ở trên Laravel5 và điều này đã giúp. Tôi chạy 'DB :: chọn ('SET NOCOUNT ON; EXEC archive_procedure');' và nó hoạt động hoàn hảo. –

0

Nếu bạn đang sử dụng một StoredProcedure và làm một cái gì đó như:

DB::select("EXEC [storedprocedure] $param1,$param2;"); 

Theo trên, PDO hy vọng báo cáo kết quả DB::select trở lại một số dữ liệu. Nhưng khi StoredProcedure của bạn không trả lại bất kỳ dữ liệu, bạn có thể thay đổi DB::select ĐẾN DB::update như belows:

DB::update("EXEC [storedprocedure] $param1,$param2;"); 

Sau này lỗi nên không còn xuất hiện.

2

Tôi chạy vào vấn đề này và các câu trả lời ở trên đã giúp, nhưng các câu trả lời ở đây giả định điều:

  1. Bạn có thể truy cập modfy sproc với SET NOCOUNT ON và bạn muốn làm điều này
  2. Bạn chắc chắn bạn cần phải di chuyển đến rowset tiếp theo $statement->nextRowset();

Trong trường hợp của tôi, tôi đang sử dụng một phương pháp tổng quát để kéo lại dữ liệu từ nhiều sprocs nơi tôi có thể hoặc có thể không có i này vấn đề và cần kiểm tra trước khi tăng các rowset.

tôi sử dụng như sau:

while($stmt->columnCount() === 0 && $stmt->nextRowset()) { 
    // Advance rowset until we get to a rowset with data 
} 

if($stmt->columnCount() > 0) { 
    // We found something with data, do stuff. 
    // Code here 
} 

Hy vọng rằng đây sẽ giúp người khác chạy vào một vấn đề tương tự.

Các vấn đề liên quan