2011-01-01 38 views
5

Tôi đã có một số thủ tục được lưu trữ được thực hiện với MySQL Workbench. Họ làm việc tốt khi sử dụng MySQL bàn làm việc để đưa chúng vào DB thử nghiệm của tôi.Làm thế nào để chèn/tạo các thủ tục lưu sẵn trong mySQL từ PHP?

Bây giờ tôi đang chuẩn bị các kịch bản tạo DB để triển khai và đây là cách duy nhất gây rắc rối cho tôi. Khi tôi sử dụng dòng lệnh/mysql shell, kịch bản hoạt động hoàn toàn tốt. Chỉ khi tôi sử dụng giao diện mysql (i) PHP để thực thi kịch bản - nó không thành công. Không một lời bình.

Tôi sử dụng tập lệnh tạo thủ tục làm bàn làm việc MySQL tạo cho tôi; có nghĩa là, nó có mô hình này:

SET @[email protected]@UNIQUE_CHECKS, UNIQUE_CHECKS=0; 
SET @[email protected]@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0; 
SET @[email protected]@SQL_MODE, SQL_MODE='TRADITIONAL'; 

vào lúc bắt đầu của kịch bản, sau đó lặp đi lặp lại cho mỗi thủ tục:

DELIMITER $$ 
USE `dbname`$$ 
CREATE PROCEDURE `procname`(IN inputparameters) 
BEGIN 

... thủ tục goes here

; 
END$$ 
DELIMITER ; 

Kịch bản này hoạt động tốt nếu chạy từ MySQL Workbench. Nó cũng chạy tốt nếu tôi cố gắng tương tự từ dòng lệnh mysql. Nhưng nó không thực hiện được bất cứ điều gì khi tôi thực hiện nó thông qua giao diện mysqli PHP (thực hiện nó với mysqli_multi_query, nó hoạt động tốt cho các kịch bản khác tạo và điền vào DB). Không có lỗi trả về trên giao diện, không có kết quả (!). Tất cả những gì tôi nhận được là "sai", và thế là xong. mã lỗi là 0, không có thông báo lỗi.

Đó là một WTF lớn đối với tôi, và tôi hy vọng bạn có thể chỉ cho tôi đúng hướng - làm thế nào tôi có thể sửa lỗi này và cài đặt các thủ tục từ PHP?

PS: quyền truy cập root/admin được cung cấp và xác minh (sau khi tất cả, tôi vừa tạo DB với cùng một kết nối, người dùng đã tạo, bảng đã chèn, v.v.).

+0

Thử xóa sử dụng 'dbname'. Cũng thử chạy nếu sử dụng lệnh mysqli_query. – Knubo

+0

Tôi đã xóa tuyên bố USE đó, không có hiệu lực. mysqli_query cũng không thành công - và trong trường hợp này, rõ ràng tại sao: chuỗi chứa nhiều câu lệnh, vì vậy nếu nó * được thực hiện đúng, nó sẽ trả về nhiều kết quả - mysqli_query không xử lý. - đối với các tập lệnh khác, mysqli_multi_query hoạt động hoàn toàn tốt, trả về một hàng kết quả cho mỗi câu lệnh. (hàng trống trên thành công, lưu ý: 1051 dòng như phản ứng để hiển thị cảnh báo; - tất cả như mong đợi). – foo

+0

Tôi đang tiến gần hơn - không có giải pháp, nhưng là một chẩn đoán. DELIMITER dường như được triển khai phía máy khách (!). – foo

Trả lời

5

Tôi chưa thử nghiệm, nhưng tôi sẽ không ngạc nhiên bởi mysqli_multi_query() mong muốn có cùng một dấu phân cách của mỗi truy vấn. Cố gắng tạo gói tạo thủ tục được lưu trữ trong một truy vấn, mà không sử dụng công cụ sửa đổi DELIMITER?

Vì vậy, thay vì

<?php 
$results = mysqli_multi(
    'DELIMITER $$ 
    USE `dbname`$$ 
    CREATE PROCEDURE `procname`(IN inputparameters) 
    BEGIN 
    ... procedure goes here 

    ; 
    END$$ 
    DELIMITER ; 
'); 
?> 

Chỉ cần làm điều này

<?php 
$result = mysqli_query('CREATE PROCEDURE `procname`(IN inputparameters) BEGIN ...; END'); 

Và cho chúng tôi biết nếu nó hoạt động :)

+2

Điều đó hoạt động, sắp xếp. Như tôi đã viết trước đây, DELIMITER dường như được triển khai phía máy khách và giao diện mysql (i) PHP dường như thiếu một số phần mà các máy khách mySQL thực hiện - như DELIMITER. Dường như không triển khai DELIMITER chút nào. Vì vậy, gửi các thủ tục riêng biệt và không có DELIMITER hoạt động. Tuy nhiên, tôi không nghĩ rằng viết tay lại các thói quen một lần nữa và một lần nữa là một giải pháp khả thi. Đó là một số thói quen, và sẽ có nhiều hơn trong tương lai. Tôi cần một cái gì đó mà làm việc * với * các công cụ tôi được đưa ra, không phải một lần nữa. Nhưng cảm ơn ý tưởng, điều này có thể giúp người khác. – foo

+1

Cảm ơn bạn, tôi đã có cùng một vấn đề, cố gắng tạo và thực hiện một thủ tục được lưu trữ từ mysqli_multi_query và nó làm việc từ HeidiSQL tuy nhiên khi tôi thực hiện cùng một mã từ PHP nó đã ném một lỗi. Tôi đã xóa các câu lệnh DELIMETER của mình và mọi ngắt dòng và nó hoạt động hoàn hảo. CẢM ƠN! : D – Jared

+0

Câu hỏi: Cách kiểm tra xem storedProcedure đã tồn tại chưa, từ PHP? –

-3

DELIMITER là cái gì đó ứng dụng mysql client thực sự sử dụng. Tôi tin rằng ứng dụng khách có trách nhiệm chia nhỏ các truy vấn mà nó gửi tới Mysql. Đó là những gì PHPMyAdmin làm, ví dụ.

Thay vì dành cả đêm để viết kịch bản để phân tích cú pháp MySQL thành truy vấn, hãy sử dụng mã tôi đã viết.Bạn sẽ tìm thấy nó trong scriptToQueries chức năng, ở đây:

http://wush.net/svn/luckyapps/pie/trunk/framework/classes/Db/Mysql.php

ENJOY

EDIT: Kể từ khi viết câu trả lời này tôi đã chuyển mã vào nền tảng Q miễn phí mà bạn có thể nghiên cứu các mã: https://github.com/EGreg/Platform/blob/master/platform/classes/Db/Mysql.php#L824

+0

hoạt động đúng hướng. cảm ơn! – foo

+4

Liên kết tham chiếu đến trang .htaccess'/'.htpasswd' được bảo vệ bằng mật khẩu. – automatix

+0

các bạn hãy thử ngay bây giờ –

0

Để tổng hợp:

DELIMITER được triển khai phía máy khách chứ không phải máy chủ.

Nếu bạn có trình điều khiển hoặc API tốt, nó có thể giải quyết vấn đề này. PHP mysql/mysqli, kể từ bây giờ, không.

Nếu bạn cần sử dụng dấu tách khác (ví dụ: do dấu phân cách mặc định xuất hiện bên trong tập lệnh), bạn phải mã hóa/thoát SQL của mình hoặc chia nhỏ nó để không cần phải thay đổi dấu phân cách. Không có sự trợ giúp nào từ PHP ở đây.

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