Zmiana znaczenia znaku ampersand w ciągu SQL

143

Próbuję wysłać zapytanie do określonego wiersza według nazwy w mojej bazie danych sql i ma ampersand. Próbowałem ustawić znak ucieczki, a następnie uciec przed ampersandem, ale z jakiegoś powodu to nie działa i nie jestem pewien, na czym dokładnie polega mój problem.

Set escape '\'
    select * from V1144engine.T_nodes where node_id in(
    select node2_id from V1144engine.T_edges where node1_id in(
    select node2_id from V1144engine.T_edges where node1_id in(
    select node2_id from V1144engine.T_edges where node1_id = 
      (select node_id from V1144engine.T_nodes where node_name = 'Geometric Vectors \& Matrices')))
    and edge_type_id = 1)
    and node_type_id = 1
    and node_id in (
    select node2_id from V1144engine.T_edges where node1_id =
      (select node_id from V1144engine.T_nodes where node_name = 'Algebra II')
    and edge_type_id = 2);

Chociaż daje to podobne rozwiązanie tego pytania , problemy są postawione bardzo różnie. Mogą skończyć z tym samym rozwiązaniem, ale to nie znaczy, że pytania są takie same.

Slater Victoroff
źródło
Myślę, że nie potrzebujesz cytatu wokół postaci ucieczki ('\')
mcalex
29
set define offto najprostszy sposób na zrobienie tego.
AnBisw
1
Duplikat stackoverflow.com/questions/118190/ ...
oliver-clare

Odpowiedzi:

205

Zamiast

node_name = 'Geometric Vectors \& Matrices'

posługiwać się

node_name = 'Geometric Vectors ' || chr(38) || ' Matrices' 

38 to kod ascii dla znaku ampersand iw tej formie zostanie zinterpretowany jako ciąg, nic więcej. Spróbowałem i zadziałało.

Innym sposobem może być użycie LIKE i podkreślenia zamiast znaku „&”:

node_name LIKE 'Geometric Vectors _ Matrices' 

Szansa, że ​​znajdziesz też inny rekord, który różni się tylko tą jedną postacią, jest dość niska.

Imre Greilich
źródło
45
Zamiast tego, co nieintuicyjne chr(38), możesz to zrobićnode_name = 'Geometric Vectors &' || ' Matrices'
Jay Sullivan,
1
Dla innych biednych zagubionych dusz podobni do siebie, trzeba pamiętać, że jest chr(38), nie char(38) .
xdhmoore
Zauważ, że &w MySQL nie ma potrzeby zmiany znaku ucieczki. MySQL również nie ma tej funkcji CHR().
asmaier
113

Escape jest ustawiony \domyślnie , więc nie musisz go ustawiać; ale jeśli tak, nie zawijaj tego w cudzysłów.

Ampersand jest znacznikiem zmiennej substytucyjnej SQL * Plus ; ale możesz to zmienić lub, co bardziej przydatne w twoim przypadku, całkowicie go wyłączyć, za pomocą:

set define off

Wtedy nie musisz w ogóle zawracać sobie głowy ucieczką od wartości.

Alex Poole
źródło
2
Znak zmiany znaczenia jest \ domyślnie ustawiony na , ale parametr boolowski escapejest domyślnie ustawiony na WYŁ. Więc OP może nie potrzebować ustawiać znaku ucieczki, ale musi to przynajmniej SET ESCAPE ONzrobić, aby to zadziałało. Lub oczywiście skorzystaj z innych, lepszych rozwiązań.
mathguy
46

Możesz użyć

set define off

Użycie tego nie zapyta o dane wejściowe

Ankur
źródło
32

prosto z książki o podstawach Oracle sql

SET DEFINE OFF
select 'Coda & Sid' from dual;
SET DEFINE ON

jak można od tego uciec bez ustalania definicji.

rzymski
źródło
2
Pomocne jest dodanie opcji SET DEFINE ON.
KSev,
@Roman Bez zdefiniowania również możesz użyć: wybierz 'Coda' '&' 'Sid' z dual; (podwójne cudzysłowy)
antcalvente
8

Aby uciec &, możesz spróbować następujących sposobów: -

  1. set scan off
  2. set define off
  3. set escape on następnie zamień &na/&
  4. wymienić &na&&

Jeden z nich powinien przynajmniej działać.

Dodatkowo, jeśli używasz programisty PL / SQL, na dole okna sql znajduje się ikona &, przejdź tam i wyłącz . Uwaga w starszej wersji tej opcji nie ma.

Upewnij się również, że set define off jest napisane na samym początku skryptu.

AConsumer
źródło
2

Działa to również:

select * from mde_product where cfn = 'A3D"&"R01'

definiujesz &jako literał przez umieszczenie "&"w ciągu znaków podwójnych qoutes .

copmac
źródło
1
Jeśli to zrobisz, podwójne cudzysłowy staną się częścią ciągu, na przykład:A3D"&"R01
David Balažic
2
set escape on
... node_name = 'Geometric Vectors \& Matrices' ...

lub alternatywnie:

set define off
... node_name = 'Geometric Vectors & Matrices' ...

Pierwsza pozwala na użycie ukośnika odwrotnego do zmiany znaku &.

Drugi wyłącza się & „globalnie” (nie trzeba nigdzie dodawać ukośnika). Możesz go ponownie włączyć, gdy set define oni od tego wiersza znaki ampersand odzyskają swoje specjalne znaczenie, więc możesz je wyłączyć dla niektórych części skryptu, a nie dla innych.

David Balažic
źródło
0
REPLACE(<your xml column>,'&',chr(38)||'amp;')
user6385350
źródło
0

Napisałem wyrażenie regularne, aby pomóc znaleźć i zamienić „&” w INSERT, mam nadzieję, że to komuś pomoże.

Sztuczka polegała na upewnieniu się, że „&” występuje z innym tekstem.

Odnaleźć “(\'[^\']*(?=\&))(\&)([^\']*\')”

Zastąpić “$1' || chr(38) || '$3”

that_roy
źródło