Thoát ký tự trích dẫn đơn để sử dụng trong truy vấn SQLite


179

Tôi đã viết lược đồ cơ sở dữ liệu (chỉ có một bảng cho đến nay) và các câu lệnh INSERT cho bảng đó trong một tệp. Sau đó, tôi đã tạo cơ sở dữ liệu như sau:

$ sqlite3 newdatabase.db
SQLite version 3.4.0
Enter ".help" for instructions
sqlite> .read ./schema.sql
SQL error near line 16: near "s": syntax error

Dòng 16 của tập tin của tôi trông giống như thế này:

INSERT INTO table_name (field1, field2) VALUES (123, 'Hello there\'s');

Vấn đề là nhân vật thoát cho một trích dẫn. Tôi cũng đã thử thoát hai lần trích dẫn (sử dụng \\\'thay vì \'), nhưng điều đó cũng không hiệu quả. Tôi đang làm gì sai?

Câu trả lời:


293

Hãy thử nhân đôi các trích dẫn đơn (nhiều cơ sở dữ liệu mong đợi theo cách đó), vì vậy nó sẽ là:

INSERT INTO table_name (field1, field2) VALUES (123, 'Hello there''s');

Trích dẫn có liên quan từ các tài liệu :

Hằng số chuỗi được hình thành bằng cách đặt chuỗi trong dấu ngoặc đơn ('). Một trích dẫn trong chuỗi có thể được mã hóa bằng cách đặt hai trích dẫn đơn liên tiếp - như trong Pascal. Các lối thoát kiểu C sử dụng ký tự dấu gạch chéo ngược không được hỗ trợ vì chúng không phải là SQL chuẩn. Chữ BLOB là chuỗi ký tự chuỗi chứa dữ liệu thập lục phân và đứng trước một ký tự "x" hoặc "X". ... Một giá trị theo nghĩa đen cũng có thể là mã thông báo "NULL".


8
Ngoài ra, hãy xem xét sử dụng các tham số ràng buộc nếu ngôn ngữ máy chủ hỗ trợ chúng (hầu hết đều làm được, nhưng vỏ SQLite thì không). SQL sau đó sẽ được INSERT INTO table_name (field1, field2) VALUES (?, ?)và các giá trị sẽ được cung cấp trực tiếp (và không có sự thay thế).
Donal Fellows

1
Chúng ta không thể sử dụng dấu ngoặc kép? như: XÁC NHẬN VÀO tên_bảng (trường1, trường2) GIÁ TRỊ (123, "Xin chào"); ?
JacksOnF1re

Ngoài ra, tùy thuộc vào tuổi thọ của chuỗi, bước đầu tiên có thể là chuyển đổi '' thành 'trước khi nhân đôi chúng lên một lần nữa.
Gary Z

44

Tôi tin rằng bạn muốn thoát ra bằng cách nhân đôi trích dẫn:

INSERT INTO table_name (field1, field2) VALUES (123, 'Hello there''s');

10

để thay thế tất cả (') trong chuỗi của bạn, hãy sử dụng

.replace(/\'/g,"''")

thí dụ:

sample = "St. Mary's and St. John's";
escapedSample = sample.replace(/\'/g,"''")

6

Chỉ trong trường hợp nếu bạn có một vòng lặp hoặc chuỗi json cần chèn vào cơ sở dữ liệu. Cố gắng thay thế chuỗi bằng một trích dẫn duy nhất. đây là giải pháp của tôi ví dụ nếu bạn có một chuỗi chứa một trích dẫn.

String mystring = "Sample's";
String myfinalstring = mystring.replace("'","''");

 String query = "INSERT INTO "+table name+" ("+field1+") values ('"+myfinalstring+"')";

cái này hoạt động với tôi trong c # và java


0

Trong C #, bạn có thể sử dụng cách sau để thay thế trích dẫn đơn bằng dấu ngoặc kép:

 string sample = "St. Mary's";
 string escapedSample = sample.Replace("'", "''");

Và đầu ra sẽ là:

"St. Mary''s"

Và, nếu bạn đang làm việc trực tiếp với Sqlite; bạn có thể làm việc với đối tượng thay vì chuỗi và bắt những thứ đặc biệt như DBNull:

private static string MySqlEscape(Object usString)
{
    if (usString is DBNull)
    {
        return "";
    }
    string sample = Convert.ToString(usString);
    return sample.Replace("'", "''");
}

0

Trong các tập lệnh bash, tôi thấy rằng việc thoát các dấu ngoặc kép xung quanh giá trị là cần thiết cho các giá trị có thể là null hoặc chứa các ký tự yêu cầu thoát (như dấu gạch nối).

Trong ví dụ này, giá trị của cộtA có thể là null hoặc chứa dấu gạch nối:

sqlite3 $db_name "insert into foo values (\"$columnA\", $columnB)";
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.