이전 블로그에서는 JavaScript에서 N1QL(SQL++)을 실행하는 방법에 대해 설명했습니다. 함수문서 처리 반복기를 통해, 데이터 조작및 오류 처리.
이제 다음으로 이동합니다. 동적 문 실행.
준비된 진술서
예를 들어 자바스크립트 함수는 다른 요청과 마찬가지로 준비된 문을 준비하고 실행할 수 있습니다:
|
1 2 3 4 5 6 7 8 9 |
함수 doPrepare() { var p = 준비 a 에서 선택 * 에서 b1; var q = 실행 a; var res = []; 에 대한 (const doc 의 q) { res.push(doc); } 반환 res; } |
|
1 |
만들기 기능 doPrepare() 언어 자바스크립트 AS "doPrepare" AT "udfblog" |
준비된 문을 준비하고 실행하는 방법에 대해 자세히 알아보기 전에 N1QL 준비된 문에 대해 몇 가지 언급해야 할 것 같습니다:
-
- N1QL 준비된 문은 요청에 대해 비공개가 아니라 전체 노드에서 공유됩니다. 다른 사람이 이전에 준비한 문을 사용하는 것은 분명히 가능하며, 오히려 권장됩니다.
- 즉, 준비된 명령문 이름의 범위는 쿼리_컨텍스트 생성 시점에 사용되었습니다. 같은 이름을 가진 두 개의 문이 동일한 쿼리_컨텍스트.
- 준비 시점에 N1QL이 이름을 할당하도록 하면 준비된 문은 다른 관계형 엔진과 크게 다르지 않습니다.
- 이름을 직접 지정하는 경우, 이름을 고유하게 유지해야 한다는 점에 유의하세요. 쿼리_컨텍스트 요청에 따라 설정합니다. 애플리케이션 접두사와 같은 고유한 명명 체계를 사용하는 것이 좋습니다.
- 또한 이미 존재하는 진술서를 작성하는 경우 진술서 텍스트는 기존 진술서의 텍스트와 일치해야 합니다. 이는 다른 사람 몰래 준비된 문장의 의미를 변경하는 것을 방지하기 위한 것입니다.
자바스크립트 함수의 준비된 문으로 돌아가기!
할 수 있습니다:
-
- 진술서 작성 및 실행
- 사용할 다른 함수/요청에 대한 문을 준비합니다.
- 기존 문을 실행합니다.
- 함수 매개변수로 전달된 문을 실행할 수도 있습니다(코드 삽입과 같이 위험할 수 있지만).
준비 및 실행
이전 예제에서 이미 명명된 문을 준비하고 실행하는 방법을 살펴보았으므로 이제 익명으로 준비된 문을 준비하고 실행하는 방법을 살펴보겠습니다.
메인에서는 다음과 같은 결과를 처리해야 합니다. 준비 문을 사용하여 이름을 추출하고 실행 문과 같은 식으로요:
|
1 2 3 4 5 6 7 8 9 10 11 12 |
함수 doPrepare() { var p = 준비 선택 * 에서 b1; var iter = p[기호.이터레이터](); var 준비 = iter.다음().값; p.닫기(); var q = N1QL("실행 \"" + 준비.이름 + "\""); var res = []; 에 대한 (const doc 의 q) { res.push(doc); } 반환 res; } |
위의 예시는 반복자를 사용하는 방법도 보여줍니다. 보기 흉하다면 준비 결과를 반복하여 이름을 가져올 수도 있습니다:
|
1 2 3 4 5 6 7 8 9 10 |
함수 doPrepare() { var p = 준비 선택 * 에서 b1; 에 대한 (준비 의 p); var q = N1QL("실행 \"" + 준비.이름 + "\""); var res = []; 에 대한 (const doc 의 q) { res.push(doc); } 반환 res; } |
위의 예는 다음과 같은 이유로 작동합니다. 준비 는 하나의 문서, 준비된 문 계획 및 변수 범위만 반환합니다. 준비 에 선언된 에 대한 루프는 실제 함수이므로 루프 자체의 끝을 지나서 볼 수 있습니다.
공정하게 말하자면 두 예 모두 특별히 우아해 보이지는 않지만 여전히 그렇습니다.
주의해야 할 점은 실행 는 매개 변수를 허용하지 않으므로 문 문자열을 구성해야 하며, 이는 곧 N1QL() 함수입니다.
이 특정 예제에서는 문제가 되지 않지만, 한편으로는 분산 형식으로 지정된 문 이름을 처리할 수 있도록 하기 위해 문 이름을 따옴표로 묶는 것이 가장 좋지만, 더 중요한 것은 N1QL 주입의 위험을 피하기 위해 문 이름이 함수에 매개 변수로 전달되었다고 가정할 때입니다:
|
1 2 3 4 5 6 7 8 |
함수 doExecuteName(이름) { var q = N1QL("실행 " + 이름); var res = []; 에 대한 (const doc 의 q) { res.push(doc); } 반환 res; } |
|
1 |
만들기 기능 doExecuteName(이름) 언어 자바스크립트 AS "doExecuteName" AT "udfblog" |
악의적인 사용자가 실행할 수도 있습니다:
|
1 |
실행 함수 doExecute("함수 doSomethingNasty()") |
이름을 따옴표로 묶지 않았다면 준비된 문장이 아니라 잠재적으로 위험한 함수를 실행했을 것입니다!
이렇게 하면 위험을 피할 수 있습니다:
|
1 2 3 4 5 6 7 8 |
함수 doExecuteName(이름) { var q = N1QL("실행 \"" + 이름 + "\""); var res = []; 에 대한 (const doc 의 q) { res.push(doc); } 반환 res; } |
EXECUTE 문에 자리 표시자 값 전달하기
준비된 문을 실행할 때 자리 표시자 값을 전달해야 하는 경우가 많습니다.
위치 자리 표시자의 경우, 이것은 준비되지 않은 문과 실제로 다르지 않습니다. N1QL() 함수, 예를 들어
|
1 |
준비 s1 FROM 선택 * FROM b1 어디 f1 > $1; |
|
1 2 3 4 5 6 7 8 |
함수 doExecute() { var q = N1QL("실행 S1", [1]); var res = []; 에 대한 (const doc 의 q) { res.push(doc); } 반환 res; } |
|
1 |
만들기 기능 doExecute() 언어 자바스크립트 AS "doExecute" AT "udfblog" |
명명된 매개변수와 관련하여 고려해야 할 사항은 다음과 같습니다:
-
- 트랜스파일러는 준비된 문 텍스트에 대한 가시성이 없으며, 구문 분석 및 재작성하는 것은 EXECUTE 문일 뿐입니다. 따라서 트랜스파일러는 어떤 변수 이름을 사용하여 N1QL() 호출합니다.
- 그리고 실행 ... 사용 문에서 정적 값만 허용합니다. 사용 절에 정의된 매개변수와 요청 본문에 정의된 매개변수 사이의 모호성을 피하기 위한 것입니다. 사용 절을 사용합니다.
결과적으로 정적 값(문자열, 숫자 등)을 사용하지 않는 한, 여기서 실행 ... 사용 가 실행 가능한 옵션(명명된 매개 변수의 경우에도)이 될 수 있지만, 현재 실행 가능한 유일한 옵션은 N1QL() 함수입니다:
|
1 |
준비 s2 FROM 선택 * FROM b1 어디 f1 > $분; |
|
1 2 3 4 5 6 7 8 |
함수 doExecute() { var q = N1QL("실행 S2", {분: 1}); var res = []; 에 대한 (const doc 의 q) { res.push(doc); } 반환 res; } |
이후 릴리스에서는 트랜스파일러가 확장되어 다음을 처리할 수 있습니다. 실행 문을 사용합니다.
준비된 문 및 루프
다음 함수를 고려하세요:
|
1 2 3 4 5 6 |
함수 doCopyField() { var q = 선택 * FROM b1 어디 f1 IS NOT 누락; 에 대한 (const doc 의 q) { var i = 삽입 INTO b1 가치(UUID(), { "f2": $doc.b1.f1 }); } } |
|
1 |
만들기 기능 doCopyField() 언어 자바스크립트 AS "doCopyField" AT "udfblog" |
이 함수가 수행하는 작업은 삽입 문을 검색할 수 있습니다.
이를 위해서는 자바스크립트 워커가 N1QL 서비스에 구문을 분석하고 삽입 문을 검색할 수 있습니다.
더 좋은 방법은 준비된 문을 사용하는 것입니다:
|
1 2 3 4 5 6 7 |
함수 doCopyField() { var p = 준비 ins FROM 삽입 INTO b1 가치(UUID(), {"f2": $1}); var q = 선택 * FROM b1 어디 f1 IS NOT 누락; 에 대한 (const doc 의 q) { var i = N1QL("실행 인", [doc.b1.f1]); } } |
결론
이제 JavaScript 함수 내에서 N1QL 문을 실행하여 데이터를 수집하고 조작하는 모든 가능한 방법에 대해 살펴보았습니다.
다음으로 다음과 같은 몇 가지 고급 주제를 다룹니다. 중첩 함수 호출, 보안 그리고 거래.