복붙노트

[SQL] 액세스 SQL에서 '이스케이프

SQL

액세스 SQL에서 '이스케이프

이 같은 뭔가 VBA에서 도메인 조회를 할 노력하고있어 :

DLookup("island", "villages", "village = '" & txtVillage & "'")

txtVillage 때까지이 작품 벌금은 아포스트로피는 따옴표로 촬영 딜런의 베이 같은이며, 나는 런타임 오류가 발생합니다.

나는 작은 따옴표를 탈출 사소한 기능을 작성했습니다 - 그것은 '' ''과 '' '대체합니다. 이것은 꽤 자주 오는 것이 보인다,하지만 난에 대한 참조를 찾을 수없는 내장 같은 작업을 수행 기능. 내가 뭔가를 놓친 적이 있습니까?

해결법

  1. ==============================

    1.은 "바꾸기"기능은 트릭을해야한다. 위의 코드를 기반으로 :

    은 "바꾸기"기능은 트릭을해야한다. 위의 코드를 기반으로 :

    DLookup("island", "villages", "village = '" & Replace(txtVillage, "'", "''") & "'")
    
  2. ==============================

    2.그것은 당신이 생각하는 것보다 더 나쁜. 누군가가이 같은 값을 입력 한 경우 일어날 것, 그리고 당신은 아무것도 탈출하지 않은 것에 대해 생각 :

    그것은 당신이 생각하는 것보다 더 나쁜. 누군가가이 같은 값을 입력 한 경우 일어날 것, 그리고 당신은 아무것도 탈출하지 않은 것에 대해 생각 :

    '); DROP TABLE [YourTable]
    

    예쁘지 않은.

    이 처리하는 올바른 방법은 쿼리 매개 변수를 사용하기 때문에 더 간단 아포스트로피 탈출에 함수가 내장되어있어 그 이유입니다. 는 OLE / 액세스 스타일의 쿼리에 대한 당신의 쿼리 문자열로이 설정 것입니다 :

    DLookup("island", "village", "village = ? ")
    

    그리고 별도로 매개 변수를 설정합니다. 당신은 VBA에서 매개 변수 값 설정에 대한 이동하는 방법 그래도 난 모르겠어요.

  3. ==============================

    3.등을 DLookup로 속기 도메인 기능을 유혹되어 있지만, 그들은 자신의 단점이있다. 등가 제트 SQL은 같은 것입니다

    등을 DLookup로 속기 도메인 기능을 유혹되어 있지만, 그들은 자신의 단점이있다. 등가 제트 SQL은 같은 것입니다

    SELECT FIRST(island)
    FROM villages
    WHERE village = ?;
    

    하나 개 이상의 일치하는 후보가 있다면 그것은 '첫 번째'이다 구현 (SQL 엔진)에 의존하고 제트 / ACE 엔진 IIRC에 대한 정의되지 않은 정의를 하나 '첫 번째'선택됩니다. 하나는 첫번째 될 것이라고 알고 계십니까? 당신은 다음을 DLookup 놀지 않는 경우 :

    [관심, 제트 / ACE에 대한 대답 중 하나는 데이터베이스 파일이 마지막으로 압축 된 시간이나 데이터베이스가 압축 적이없는 경우 첫 번째 (유효 시간) 삽입 값의 clusterd 지수에 따라 최소의 값이됩니다. persent 그렇지 UNIQUE 제약 또는 인덱스 NOT NULL 컬럼에 정의되어있는 경우에는 클러스터 된 인덱스 차례로 달리 제 (유효 시간) 삽입 된 행의 PRIAMRY KEY에 의해 결정된다. 하나는 클러스터링을 위해 사용되는 NOT NULL 컬럼에 하나 개 이상의 UNIQUE 제약 조건 또는 인덱스가 정의 된 경우는 어떻게? 나는 아무 생각도 없어! 난 당신이 '첫 번째'당신이 방법을 알고 경우에도, 결정하기 쉽지 않다 아이디어를 얻을 신뢰!]

    나는 또한보기의 최적화 관점에서 도메인 집계 함수를 사용하지 않는 것이 마이크로 소프트의 조언을 본 적이 :

    Access 데이터베이스의 쿼리 성능에 대한 정보 http://support.microsoft.com/kb/209126

    "등을 DLookup 함수와 도메인 집계 함수를 사용하지 마십시오 ... Jet 데이터베이스 엔진 할 수없는 최적화 쿼리가 사용하는 도메인 집계 함수"

    쿼리를 사용하여 다시 쓰기를 선택하면 다음 매개 변수 구문을 활용하거나, 제트 4.0 / ACE 절차 구문 예를 선호 할 수 있습니다 같은

    CREATE PROCEDURE GetUniqueIslandName
    (
       :village_name VARCHAR(60)
    )
    AS 
    SELECT V1.island_name
      FROM Villages AS V1
     WHERE V1.village_name = :village_name
           AND EXISTS 
           (
            SELECT V2.village_name
              FROM Villages AS V2
             WHERE V2.village_name = V1.village_name
             GROUP 
                BY V2.village_name
            HAVING COUNT(*) = 1
           );
    

    필요에 따라 모든 문자를 (단지 이중 - 작은 따옴표되지 않음) 탈출 - 또는 적어도 그 데이터 공급자의 - 당신이 엔진의 고유 기능을 사용할 수 있습니다이 방법.

  4. ==============================

    4.내가 액세스 대하 $ (34)를 사용하고 행복하게 작은 따옴표를 가질 수 있다고 생각 / 내 아포스트로피. 예를 들어,

    내가 액세스 대하 $ (34)를 사용하고 행복하게 작은 따옴표를 가질 수 있다고 생각 / 내 아포스트로피. 예를 들어,

    DLookup("island", "villages", "village = " & chr$(34) & nonEscapedString & chr$(34))
    

    다음하지만 당신은 ( ")는 CHR의 $ (34)를 탈출해야 할 것

    당신은 대체 기능을 사용할 수 있습니다.

    Dim escapedString as String
    
    escapedString = Replace(nonescapedString, "'", "''")
    
  5. ==============================

    5.조엘 Coehoorn 같은 제안 매개 변수화 쿼리 대신 쿼리 문자열에 연결을하는, 갈 수있는 방법입니다. 첫째 - 나는 엔진의 자신의 손으로 탈출 걸립니다 합리적으로 확신 당신은 그것에 대해 걱정할 필요가 없습니다 - 둘째, 특정 보안 위험을 방지 할 수 있습니다.

    조엘 Coehoorn 같은 제안 매개 변수화 쿼리 대신 쿼리 문자열에 연결을하는, 갈 수있는 방법입니다. 첫째 - 나는 엔진의 자신의 손으로 탈출 걸립니다 합리적으로 확신 당신은 그것에 대해 걱정할 필요가 없습니다 - 둘째, 특정 보안 위험을 방지 할 수 있습니다.

  6. ==============================

    6.그러나, 그것은 다음과 같이해야한다 (하나 더 각을 doublequote) :

    그러나, 그것은 다음과 같이해야한다 (하나 더 각을 doublequote) :

    sSQL = "SELECT * FROM tblTranslation WHERE fldEnglish=""" & myString & """;"
    

    아니면 내가 무엇을 선호한다 :

    당신의 문자열로 "탈출" "[]"이러한 문자를 허용하지 않기 때문에, 작은 따옴표를 탈출하는 함수를 만들 ...

    Public Function fncSQLStr(varStr As Variant) As String
    
    If IsNull(varStr) Then
            fncSQLStr = ""
        Else
            fncSQLStr = Replace(Trim(varStr), "'", "''")
        End If
    
    End Function
    

    나는 SELECT, INSERT 및 UPDATE 같은 내 모든 SQL-쿼리에 대해이 기능을 사용 (그리고 WHERE 절에뿐만 아니라 ...)

    strSQL = "INSERT INTO tbl" & 
        " (fld1, fld2)" & _
        " VALUES ('" & fncSQLStr(str1) & "', '" & fncSQLStr(Me.tfFld2.Value) & "');"
    

    또는

    strSQL = "UPDATE tbl" & _
        " SET fld1='" & fncSQLStr(str1) & "', fld2='" & fncSQLStr(Me.tfFld2.Value) & "'" & _
        " WHERE fld3='" & fncSQLStr(str3) & "';"
    
  7. ==============================

    7.그런데, 여기 내 EscapeQuotes 기능입니다

    그런데, 여기 내 EscapeQuotes 기능입니다

    Public Function EscapeQuotes(s As String) As String
    
        If s = "" Then
            EscapeQuotes = ""
        ElseIf Left(s, 1) = "'" Then
            EscapeQuotes = "''" & EscapeQuotes(Mid(s, 2))
        Else
            EscapeQuotes = Left(s, 1) & EscapeQuotes(Mid(s, 2))
        End If
    
    End Function
    
  8. ==============================

    8.작은 따옴표에 문제가과 기능을 대체하는 사람들의 경우,이 라인은 ^ o ^ 하루 저장할 수 있습니다

    작은 따옴표에 문제가과 기능을 대체하는 사람들의 경우,이 라인은 ^ o ^ 하루 저장할 수 있습니다

    Replace(result, "'", "''", , , vbBinaryCompare)
    
  9. ==============================

    9.거기에 아포스트로피가있을 수 있습니다 기준 주위에 괄호를 넣어.

    거기에 아포스트로피가있을 수 있습니다 기준 주위에 괄호를 넣어.

    뭔가 같은 :

    DLookup("island", "villages", "village = '[" & txtVillage & "]'")
    

    그들은 작은 따옴표 밖에하거나 같은 txtVillage 주위해야 할 수 있습니다 :

    DLookup("island", "villages", "village = '" & [txtVillage] & "'")
    

    당신이 바로 그 조합을 발견하면, 그것은 아포스트로피 처리됩니다.

    키스 B

  10. ==============================

    10.내 솔루션은 매우 간단합니다. 원래, 나는 ADO 레코드 집합을 만들려면이 SQL 표현식을 사용 :

    내 솔루션은 매우 간단합니다. 원래, 나는 ADO 레코드 집합을 만들려면이 SQL 표현식을 사용 :

    Dim sSQL as String
    sSQL="SELECT * FROM tblTranslation WHERE fldEnglish='" & myString & "';"
    

    MyString의 그것에 아포스트로피가 있었을 때, 국제 전기처럼, 내 프로그램이 중단됩니다. 사용 따옴표 문제를 해결했다.

    sSQL="SELECT * FROM tblTranslation WHERE fldEnglish="" & myString & "";"
    
  11. from https://stackoverflow.com/questions/199889/escaping-in-access-sql by cc-by-sa and MIT license