Jak uniknąć pojedynczej wyceny w programie SQL Server?


956

Próbuję insertprzenieść dane tekstowe do tabeli w SQL Server9.

Tekst zawiera pojedynczy cytat (').

Jak mam uciec?

Próbowałem użyć dwóch pojedynczych cudzysłowów, ale rzuciło mi to trochę błędów.

na przykład. insert into my_table values('hi, my name''s tim.');


30
„rzuciło mi kilka błędów” - jakie były te błędy?
llamaoo7

Tak, ponieważ właściwym sposobem wstawiania pojedynczych cudzysłowów w MSSQL jest ich podwojenie. Przykład, który nam pokazujesz, powinien działać. Jak wykonać zapytanie SQL w jakim języku? Czy jest to w SQL Server Management Studio?
MaxiWheat,

Odpowiedzi:


1387

Pojedyncze cytaty są unikane przez podwojenie ich , tak jak pokazałeś nam w swoim przykładzie. Poniższy kod SQL ilustruje tę funkcjonalność. Przetestowałem to na SQL Server 2008:

DECLARE @my_table TABLE (
    [value] VARCHAR(200)
)

INSERT INTO @my_table VALUES ('hi, my name''s tim.')

SELECT * FROM @my_table

Wyniki

value
==================
hi, my name's tim.

16
szukałem niewłaściwego miejsca, aby naprawić mój problem. w końcu nie była to kwestia ucieczki postaci. mój problem polegał na tym, że długość danych przekroczyła limit. dzięki za uspokojenie mnie, że dwukrotne użycie pojedynczego cytatu jest właściwym sposobem na ucieczkę od postaci.
tim_wonil

Więc jeśli mam tekst zawierający 10 000 słów, konieczne będzie zastąpienie całego tekstu?
Vinicius Lima

3
@ ViniciusLima: Krótka odpowiedź brzmi: tak. Zmieniłoby się to oczywiście w zależności od technologii, której będziesz używać do przechowywania danych. Jeśli używasz ORM, zrobi to za Ciebie. Jeśli budujesz polecenia SQL ręcznie, będziesz chciał użyć funkcji „przygotowanych instrukcji” języka. Jeśli robisz to w Management Studio, będziesz musiał dokonać wymiany.
Cᴏʀʏ

1
tj. dwa pojedyncze cytaty dla jednego. [''] => [']
Ujjwal Singh

67

Jeśli unikanie pojedynczego cytatu z innym pojedynczym cytatem nie działa dla Ciebie (tak jak w przypadku jednego z moich ostatnich REPLACE()zapytań), możesz użyćSET QUOTED_IDENTIFIER OFF przed zapytaniem, a następnie SET QUOTED_IDENTIFIER ONpo zapytaniu.

Na przykład

SET QUOTED_IDENTIFIER OFF;

UPDATE TABLE SET NAME = REPLACE(NAME, "'S", "S");

SET QUOTED_IDENTIFIER ON;
-- set OFF then ON again

2
Zwykle korzystam z podejścia podwójnego, ale tam, gdzie generowałem dynamiczny SQL, który był następnie uruchamiany na wielu serwerach i bazach danych, to rozwiązanie działało dla mnie, podczas gdy podwajanie nie w jednym konkretnym przypadku. Dzięki za to!
Richard Moss,

Zachowaj ostrożność, odwołując się do widoków i indeksów w kolumnach obliczeniowych, ponieważ może wystąpić błąd. stackoverflow.com/questions/9235527/…
data

@RichardMoss, +1. ten sam scenariusz z tobą. podwójne podejście jest początkowym rozwiązaniem. W przypadku złożonych zapytań, takich jak dynamiczny SQL na wielu serwerach, to zadziała, podejście może być podwojone
Edgar Allan Bayron,


17

Podwojenie cytatu powinno było zadziałać, więc dziwne, że nie zadziałało; alternatywą jest jednak stosowanie ciągów podwójnych cudzysłowów zamiast pojedynczych. To znaczy,

insert into my_table values("hi, my name's tim.");


4
Co jeśli tekst zawiera zarówno pojedyncze, jak i podwójne cudzysłowy? Czy podwójne cudzysłowy nie są zarezerwowane tylko dla nazw pól?
Lajos Meszaros

11

2 sposoby obejścia tego:


za 'po prostu można podwoić w ciągu, np select 'I''m happpy'- dostanie:I'm happy


Dla dowolnego charaktera nie jesteś pewien: na serwerze sql możesz uzyskać kod Unicode dowolnego char select unicode(':') (zachowujesz numer)

Więc ten przypadek możesz również select 'I'+nchar(39)+'m happpy'


6

Kolejną rzeczą, na którą należy uważać, jest to, czy naprawdę jest przechowywana jako klasyczny ASCII '(ASCII 27) lub Unicode 2019 (który wygląda podobnie, ale nie tak samo).

Nie jest to wielka sprawa na temat wkładek, ale może oznaczać świat na wybranych i aktualizacjach.
Jeśli jest to wartość Unicode, wówczas ucieczka od „w klauzuli WHERE” (np. Gdzie blah = „Workers's Comp”) zwróci, tak jakby szukana wartość nie istniała, jeśli „in” Worker Comp ” wartość Unicode.

Jeśli twoja aplikacja kliencka obsługuje dane wejściowe oparte na wolnym kluczu, a także kopiowaniu i wklejaniu, może to być Unicode w niektórych wierszach i ASCII w innych!

Prostym sposobem na potwierdzenie tego jest wykonanie jakiegoś otwartego zapytania, które przywróci poszukiwaną wartość, a następnie skopiowanie i wklejenie go do notatnika ++ lub innego edytora obsługującego Unicode.

Różnice w wyglądzie między wartością ascii a wartością Unicode powinny być oczywiste dla oczu, ale jeśli pochylisz się w kierunku odbytu, pojawi się on jako 27 (ascii) lub 92 (Unicode) w edytorze szesnastkowym.


4

Wielu z nas wie, że popularną metodą unikania pojedynczych cytatów jest ich podwajanie, tak jak poniżej.

PRINT 'It''s me, Arul.';

Podwajanie metody pojedynczych cytatów

przyjrzymy się innym alternatywnym sposobom unikania pojedynczych cytatów.

1. znaki UNICODE

39 to UNIKODOWY znak pojedynczego cytatu. Możemy więc użyć go jak poniżej.

PRINT 'Hi,it'+CHAR(39)+'s Arul.';
PRINT 'Helo,it'+NCHAR(39)+'s Arul.';

Znaki UNICODE

2.QUOTED_IDENTIFIER

Innym prostym i najlepszym alternatywnym rozwiązaniem jest użycie QUOTED_IDENTIFIER. Gdy QUOTED_IDENTIFIER jest ustawiony na OFF, ciągi znaków mogą być ujęte w podwójne cudzysłowy. W tym scenariuszu nie musimy uciekać przed pojedynczymi cudzysłowami. Tak więc ten sposób byłby bardzo pomocny przy użyciu wielu wartości ciągów z pojedynczymi cudzysłowami. Będzie to bardzo pomocne podczas korzystania z tak wielu wierszy skryptów INSERT / UPDATE, w których wartości kolumn mają pojedyncze cudzysłowy.

SET QUOTED_IDENTIFIER OFF;
PRINT "It's Arul."
SET QUOTED_IDENTIFIER ON;

QUOTE_IDENTIFIER

WNIOSEK

Powyższe metody mają zastosowanie zarówno do AZURE, jak i do lokali.


1

Poniższa składnia uniknie TYLKO JEDNEGO cudzysłowu:

SELECT ''''

Rezultatem będzie pojedynczy cytat. Może być bardzo pomocny przy tworzeniu dynamicznego SQL :). wprowadź opis zdjęcia tutaj


0

To powinno działać

DECLARE @singleQuote CHAR 
SET @singleQuote =  CHAR(39)

insert into my_table values('hi, my name'+ @singleQuote +'s tim.')

0

Po prostu wstaw „przed czymkolwiek do wstawienia”. Będzie to jak znak ucieczki w sqlServer

Przykład: gdy masz pole as, nic mi nie jest . możesz zrobić: UPDATE my_table SET row = 'I'm w porządku.';


Czy nie jest to dokładnie to, co zrobiła OP, i to samo, co już mówi najlepiej głosowana odpowiedź? Przypuszczalnie musi istnieć jakieś inne źródło błędu.
Michael MacAskill

-2

To powinno zadziałać: użyj odwrotnego ukośnika i wstaw podwójny cytat

"UPDATE my_table SET row =\"hi, my name's tim.\";

Co masz na myśli? Mówisz, że PRINT \"hi, my name's tim.\";będzie działać w SSMS? To w ogóle nie działa i nikt nigdy nie powiedział, że to działa.
Mohammad Musavi

Nigdy nie zadziała.
Santosh Jadi
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.