From 0b6366834a0da969ee9327ab7cb7f3976959de9b Mon Sep 17 00:00:00 2001 From: Nikita Vasilev Date: Mon, 18 Aug 2025 14:49:50 +0300 Subject: [PATCH 1/2] [Docs] ColumnShard writes (#22392) Co-authored-by: anton-bobkov Co-authored-by: ElenaAfina <144937430+ElenaAfina@users.noreply.github.com> Co-authored-by: Anton Bobkov Co-authored-by: Ivan Blinkov --- ...itation-column-row-in-read-only-tx-warn.md | 5 + .../limitation-column-row-in-read-only-tx.md | 3 + .../core/concepts/_includes/transactions.md | 12 +- .../ydb-cli/parameterized-query-execution.md | 594 ++++++++++++++++++ .../en/core/yql/reference/syntax/delete.md | 12 +- .../core/yql/reference/syntax/insert_into.md | 22 +- .../core/yql/reference/syntax/replace_into.md | 20 +- .../en/core/yql/reference/syntax/update.md | 20 +- .../core/yql/reference/syntax/upsert_into.md | 20 +- ...itation-column-row-in-read-only-tx-warn.md | 5 + .../limitation-column-row-in-read-only-tx.md | 3 + .../core/concepts/_includes/transactions.md | 12 +- ydb/docs/ru/core/concepts/transactions.md | 2 +- .../dev/yql-tutorial/fill_tables_with_data.md | 10 +- .../ru/core/dev/yql-tutorial/insert_into.md | 10 +- .../ru/core/dev/yql-tutorial/replace_into.md | 10 +- .../ydb-cli/parameterized-queries-cli.md | 6 +- .../ydb-cli/parameterized-query-execution.md | 591 +++++++++++++++++ .../ru/core/yql/reference/syntax/delete.md | 14 +- .../core/yql/reference/syntax/insert_into.md | 14 +- .../core/yql/reference/syntax/replace_into.md | 14 +- .../ru/core/yql/reference/syntax/update.md | 16 +- .../core/yql/reference/syntax/upsert_into.md | 15 +- 23 files changed, 1247 insertions(+), 183 deletions(-) create mode 100644 ydb/docs/en/core/_includes/limitation-column-row-in-read-only-tx-warn.md create mode 100644 ydb/docs/en/core/_includes/limitation-column-row-in-read-only-tx.md create mode 100644 ydb/docs/en/core/reference/ydb-cli/parameterized-query-execution.md create mode 100644 ydb/docs/ru/core/_includes/limitation-column-row-in-read-only-tx-warn.md create mode 100644 ydb/docs/ru/core/_includes/limitation-column-row-in-read-only-tx.md create mode 100644 ydb/docs/ru/core/reference/ydb-cli/parameterized-query-execution.md diff --git a/ydb/docs/en/core/_includes/limitation-column-row-in-read-only-tx-warn.md b/ydb/docs/en/core/_includes/limitation-column-row-in-read-only-tx-warn.md new file mode 100644 index 000000000000..be17501ecb1c --- /dev/null +++ b/ydb/docs/en/core/_includes/limitation-column-row-in-read-only-tx-warn.md @@ -0,0 +1,5 @@ +{% note warning %} + +{% include [column-and-row-tables-in-read-only-tx](./limitation-column-row-in-read-only-tx.md) %} + +{% endnote %} \ No newline at end of file diff --git a/ydb/docs/en/core/_includes/limitation-column-row-in-read-only-tx.md b/ydb/docs/en/core/_includes/limitation-column-row-in-read-only-tx.md new file mode 100644 index 000000000000..a331b9e047e3 --- /dev/null +++ b/ydb/docs/en/core/_includes/limitation-column-row-in-read-only-tx.md @@ -0,0 +1,3 @@ +The simultaneous use of [column-oriented tables](../concepts/glossary.md#column-oriented-table) and [row-oriented tables](../concepts/glossary.md#row-oriented-table) is possible only in read-only transactions. Support for write transactions involving both types of tables simultaneously is under development. + +If a write transaction includes both types of tables, it fails with the following error: `Write transactions between column and row tables are disabled at current time`. \ No newline at end of file diff --git a/ydb/docs/en/core/concepts/_includes/transactions.md b/ydb/docs/en/core/concepts/_includes/transactions.md index 1e1d08830b3b..5e4e104f99f6 100644 --- a/ydb/docs/en/core/concepts/_includes/transactions.md +++ b/ydb/docs/en/core/concepts/_includes/transactions.md @@ -57,6 +57,16 @@ A [topic](../topic.md) in {{ ydb-short-name }} can be sharded into several parti ## Transactions with topics and tables {#topic-table-transactions} +{% note warning %} + +{% include [not_allow_for_olap](../../_includes/not_allow_for_olap_text.md) %} + +{% endnote %} + {{ ydb-short-name }} supports transactions involving [row-oriented tables](../glossary.md#row-oriented-table) and/or [topics](../glossary.md#topic). This makes it possible to transactionally transfer data from tables to topics and vice versa, as well as between topics. This ensures that data is neither lost nor duplicated in case of a network outage or other issues. This enables the implementation of the transactional outbox pattern within {{ ydb-short-name }}. -For more information about transactions with tables and topics in {{ ydb-short-name }}, see [{#T}](../topic.md#topic-transactions) and [{#T}](../../reference/ydb-sdk/topic.md). \ No newline at end of file +For more information about transactions with tables and topics in {{ ydb-short-name }}, see [{#T}](../topic.md#topic-transactions) and [{#T}](../../reference/ydb-sdk/topic.md). + +## Transactions with Column and Row Tables {#mixed-transactions} + +{% include [limitation](../../_includes/limitation-column-row-in-read-only-tx.md) %} diff --git a/ydb/docs/en/core/reference/ydb-cli/parameterized-query-execution.md b/ydb/docs/en/core/reference/ydb-cli/parameterized-query-execution.md new file mode 100644 index 000000000000..b02da602afaf --- /dev/null +++ b/ydb/docs/en/core/reference/ydb-cli/parameterized-query-execution.md @@ -0,0 +1,594 @@ +# Running parameterized queries + +## Overview + +{{ ydb-short-name }} CLI can execute parameterized queries. To use parameters, you need to declare them using [the YQL `DECLARE` command](../../yql/reference/syntax/declare.md) in your query text. + +The preferred way to run parameterized queries in {{ ydb-short-name }} CLI is to use the [`ydb sql`](sql.md) command. + +Parameter values can be set via the command-line arguments, uploaded from [JSON](https://en.wikipedia.org/wiki/JSON) files, and read from `stdin` in binary or JSON format. Binary data can be encoded as base64 or UTF-8. While reading from `stdin` or a file, you can stream multiple parameter values, triggering multiple query executions with batching options. + +## Why use parameterized queries? + +Using parameterized queries offers several key advantages: + +* **Enhanced Performance:** Parameterized queries significantly boost performance when executing multiple similar queries that differ only in input parameters. This is achieved through the use of [prepared statements](https://en.wikipedia.org/wiki/Prepared_statement). The query is compiled once and then cached on the server. Subsequent requests with the same query text bypass the compilation phase, allowing for immediate execution. + +* **Protection Against SQL Injection:** Another critical benefit of using parameterized queries is the protection they offer against [SQL injection](https://en.wikipedia.org/wiki/SQL_injection) attacks. This security feature ensures that the input parameters are appropriately handled, mitigating the risk of malicious code execution. + +## Executing a single query {#one-request} + +To provide parameters for a single query execution, you can use the command-line arguments, JSON files, or `stdin`, using the following {{ ydb-short-name }} CLI options: + +| Name | Description | +| --- | --- | +| `-p, --param` | The value of a single query parameter in the `name=value` or `$name=value` format, where `name` is the parameter name and `value` is its value (a valid [JSON value](https://www.json.org/json-en.html)). This option can be specified multiple times.

All specified parameters must be declared in the query using the [DECLARE operator](../../yql/reference/syntax/declare.md). Otherwise, you will receive the "Query does not contain parameter" error. If you specify the same parameter multiple times, you will receive the "Parameter value found in more than one source" error.

Depending on your operating system, you might need to escape the `$` character or enclose your expression in single quotes (`'`). | +| `--input-file` | The name of a file in [JSON](https://en.wikipedia.org/wiki/JSON) format and [UTF-8](https://en.wikipedia.org/wiki/UTF-8) encoding that contains parameter values matched against the query parameters by key names. Only one input file can be used.

If values for the same parameter are found in multiple files or set by the `--param` command-line option, you will receive the "Parameter value found in more than one source" error.

Keys that are present in the file but not declared in the query will be ignored without an error message. | +| `--input-format` | The format of parameter values applied to all sources of parameters (command line, file, or `stdin`).
Available options:
  • `json` (default): JSON format.
  • `csv`: [CSV](https://en.wikipedia.org/wiki/Comma-separated_values) format.
  • `tsv`: [TSV](https://en.wikipedia.org/wiki/Tab-separated_values) format.
  • `raw`: Input is read as parameter values with no transformation or parsing. The parameter name should be set with the `--input-param-name` option.
| +| `--input-binary-strings` | The input binary string encoding format. Defines how binary strings in the input should be interpreted.
Available options:
  • `unicode`: Every byte in binary strings that is not a printable ASCII symbol (codes 32-126) should be encoded as UTF-8.
  • `base64`: Binary strings should be fully encoded with base64.
| + +If values are specified for all non-optional (i.e., NOT NULL) parameters [in the `DECLARE` clause](../../yql/reference/syntax/declare.md), the query will be executed on the server. If a value is absent for even one such parameter, the command fails with the error message "Missing value for parameter". + +### More specific options for input parameters {#specific-param-options} + +The following options are not described in the `--help` output. To see their descriptions, use the `-hh` option instead. + +| Name | Description | +| --- | --- | +| `--input-framing` | The input framing format. Defines how parameter sets are delimited in the input.
Available options:
  • `no-framing` (default): Data from the input is taken as a single set of parameters.
  • `newline-delimited`: A newline character delimits parameter sets in the input and triggers processing according to the `--input-batch` option.
| +| `--input-param-name` | The parameter name in the input stream, required when the input format contains only values (that is, when `--input-format raw` is used). | +| `--input-columns` | A string with column names that replaces the CSV/TSV header. Relevant only when passing parameters in CSV/TSV format. It is assumed that the file does not contain a header. | +| `--input-skip-rows` | The number of CSV/TSV header rows to skip in the input data (excluding the row of column names if the `--header` option is used). Relevant only when passing parameters in CSV/TSV format. | +| `--input-batch` | The batch mode applied to parameter sets from `stdin` or `--input-file`.
Available options:
  • `iterative` (default): Executes the query for each parameter set (exactly one execution when `no-framing` is specified for `--input-framing`).
  • `full`: A simplified batch mode where the query runs only once and all the parameter sets received from the input (`stdin` or `--input-file`) are wrapped into a `List<...>`.
  • `adaptive`: Executes the query with a JSON list of parameter sets when either the number of sets reaches `--input-batch-max-rows` or the waiting time reaches `--input-batch-max-delay`.
| +| `--input-batch-max-rows` | The maximum size of the list for the input adaptive batching mode (default: 1000). | +| `--input-batch-max-delay` | The maximum delay before submitting a received parameter set for processing in the `adaptive` batch mode. The value is specified as a number with a time unit: `s` (seconds), `ms` (milliseconds), `m` (minutes), etc. Default value: `1s` (1 second).

The {{ ydb-short-name }} CLI starts a timer when it receives the first set of parameters for the batch from the input and sends the accumulated batch for execution once the timer expires. This parameter enables efficient batching when the arrival rate of new parameter sets is unpredictable. | + +### Examples {#examples-one-request} + +{% include [ydb-cli-profile](../../_includes/ydb-cli-profile.md) %} + +#### Passing the value of a single parameter {#example-simple} + +From the command line using `--param` option: + +```bash +{{ ydb-cli }} -p quickstart sql -s 'DECLARE $a AS Int64; SELECT $a' --param '$a=10' +``` + +Using a file in JSON format (which is used by default): + +```bash +echo '{"a":10}' > p1.json +{{ ydb-cli }} -p quickstart sql -s 'DECLARE $a AS Int64; SELECT $a' --input-file p1.json +``` + +Via `stdin` passing a JSON string as a set of one parameter: + +```bash +echo '{"a":10}' | {{ ydb-cli }} -p quickstart sql -s 'DECLARE $a AS Int64; SELECT $a' +``` + +Via `stdin` passing only a parameter value and setting a parameter name via the `--input-param-name` option: + +```bash +echo '10' | {{ ydb-cli }} -p quickstart sql -s 'DECLARE $a AS Int64; SELECT $a' --input-param-name a +``` + +#### Passing the values of parameters of different types from multiple sources {#example-multisource} + +```bash +# Create a JSON file with fields 'a', 'b', and 'x', where 'x' will be ignored in the query +echo '{ "a":10, "b":"Some text", "x":"Ignore me" }' > p1.json + +# Run the query using ydb-cli, passing in 'a' and 'b' from the input file, and 'c' as a direct parameter +{{ ydb-cli }} -p quickstart sql \ + -s 'DECLARE $a AS Int64; + DECLARE $b AS Utf8; + DECLARE $c AS Int64; + + SELECT $a, $b, $c' \ + --input-file p1.json \ + --param '$c=30' +``` + +Command output: + +```text +┌─────────┬─────────────┬─────────┐ +│ column0 │ column1 │ column2 │ +├─────────┼─────────────┼─────────┤ +│ 10 │ "Some text" │ 30 │ +└─────────┴─────────────┴─────────┘ +``` + +#### Passing Base64-encoded binary strings {#example-base64} + +```bash +{{ ydb-cli }} -p quickstart sql \ + -s 'DECLARE $a AS String; + SELECT $a' \ + --input-format json \ + --input-binary-strings base64 \ + --param '$a="SGVsbG8sIHdvcmxkCg=="' +``` + +Command output: + +```text +┌──────────────────┐ +| column0 | +├──────────────────┤ +| "Hello, world\n" | +└──────────────────┘ +``` + +#### Passing raw binary content directly {#example-raw} + +```bash +curl -Ls http://ydb.tech/docs/en | {{ ydb-cli }} -p quickstart sql \ + -s 'DECLARE $a AS String; + SELECT LEN($a)' \ + --input-format raw \ + --input-param-name a +``` + +Command output (the exact number of bytes may vary): + +```text +┌─────────┐ +| column0 | +├─────────┤ +| 66426 | +└─────────┘ +``` + +#### Passing CSV data {#example-csv} + +```bash +echo '10,Some text' | {{ ydb-cli }} -p quickstart sql \ + -s 'DECLARE $a AS Int32; + DECLARE $b AS String; + SELECT $a, $b' \ + --input-format csv \ + --input-columns 'a,b' +``` + +Command output: + +```text +┌─────────┬─────────────┐ +| column0 | column1 | +├─────────┼─────────────┤ +| 10 | "Some text" | +└─────────┴─────────────┘ +``` + +## Iterative streaming processing {#streaming-iterate} + +{{ ydb-short-name }} CLI supports executing a query multiple times with different sets of parameter values provided via `stdin` **or** an input file (but not both). In this case, the database connection is established once, and the query execution plan is cached. This approach significantly improves performance compared to making separate CLI calls. + +To use this feature, stream different sets of values for the same parameters to the command input (`stdin` or `--input-file`) one after another, specifying a rule for the {{ ydb-short-name }} CLI to separate the sets. + +The query is executed as many times as there are parameter value sets received from the input. Each set is combined with the parameter values defined using the `--param` options. The command completes once the input stream is closed. Each query is executed within a dedicated transaction. + +A rule for separating parameter sets (framing) complements the `--input-format` option: + +| Name | Description | +| --- | --- | +| `--input-framing` | Input framing format. Defines how parameter sets are delimited on the input.
Available options:
  • `no-framing` (default): Data from the input is taken as a single set of parameters.
  • `newline-delimited`: A newline character delimits parameter sets in the input and triggers processing according to the `--input-batch` option.
| + +{% note warning %} + +When using a newline character as a separator between parameter sets, ensure that newline characters are not used inside the parameter sets. Quoting a text value does not allow newlines within the text. Multiline JSON documents are also not allowed. + +{% endnote %} + +### Example {#example-streaming-iterate} + +#### Streaming processing of multiple parameter sets {#example-iterate} + +{% list tabs %} + +- JSON + + Suppose you need to run your query three times with the following sets of values for the `a` and `b` parameters: + + 1. `a` = 10, `b` = 20 + 2. `a` = 15, `b` = 25 + 3. `a` = 35, `b` = 48 + + Let's create a file that contains lines with JSON representations of these sets: + + ```bash + echo -e '{"a":10,"b":20}\n{"a":15,"b":25}\n{"a":35,"b":48}' | tee par1.txt + ``` + + Command output: + + ```text + {"a":10,"b":20} + {"a":15,"b":25} + {"a":35,"b":48} + ``` + + Let's execute the query by passing the content of this file to `stdin`, formatting the output as JSON: + + ```bash + cat par1.txt | \ + {{ ydb-cli }} -p quickstart sql \ + -s 'DECLARE $a AS Int64; + DECLARE $b AS Int64; + SELECT $a + $b' \ + --input-framing newline-delimited \ + --format json-unicode + ``` + + Command output: + + ```text + {"column0":30} + {"column0":40} + {"column0":83} + ``` + + Or just by passing the input file name to the `--input-file` option: + + ```bash + {{ ydb-cli }} -p quickstart sql \ + -s 'DECLARE $a AS Int64; + DECLARE $b AS Int64; + SELECT $a + $b' \ + --input-file par1.txt \ + --input-framing newline-delimited \ + --format json-unicode + ``` + + Command output: + + ```text + {"column0":30} + {"column0":40} + {"column0":83} + ``` + + This output can be passed as input to the next query command if it has a `column0` parameter. + +- CSV + + Suppose you need to run your query three times with the following sets of values for the `a` and `b` parameters: + + 1. `a` = 10, `b` = 20 + 2. `a` = 15, `b` = 25 + 3. `a` = 35, `b` = 48 + + Let's create a file that contains lines with CSV representations of these sets: + + ```bash + echo -e 'a,b\n10,20\n15,25\n35,48' | tee par1.txt + ``` + + Command output: + + ```text + a,b + 10,20 + 15,25 + 35,48 + ``` + + Let's execute the query by passing the content of this file to `stdin`, formatting the output as CSV: + + ```bash + cat par1.txt | \ + {{ ydb-cli }} -p quickstart sql \ + -s 'DECLARE $a AS Int64; + DECLARE $b AS Int64; + SELECT $a + $b' \ + --input-format csv \ + --input-framing newline-delimited \ + --format csv + ``` + + Command output: + + ```text + 30 + 40 + 83 + ``` + + Or just by passing the input file name to the `--input-file` option: + + ```bash + {{ ydb-cli }} -p quickstart sql \ + -s 'DECLARE $a AS Int64; + DECLARE $b AS Int64; + SELECT $a + $b' \ + --input-file par1.txt \ + --input-format csv \ + --input-framing newline-delimited \ + --format csv + ``` + + Command output: + + ```text + 30 + 40 + 83 + ``` + + This output can be passed as input to another command running a different parameterized query. + +- TSV + + Suppose you need to run your query three times, with the following sets of values for the `a` and `b` parameters: + + 1. `a` = 10, `b` = 20 + 2. `a` = 15, `b` = 25 + 3. `a` = 35, `b` = 48 + + Let's create a file that includes lines with TSV representations of these sets: + + ```bash + echo -e 'a\tb\n10\t20\n15\t25\n35\t48' | tee par1.txt + ``` + + Command output: + + ```text + a b + 10 20 + 15 25 + 35 48 + ``` + + Let's execute the query by passing the content of this file to `stdin`, formatting the output as TSV: + + ```bash + cat par1.txt | \ + {{ ydb-cli }} -p quickstart sql \ + -s 'DECLARE $a AS Int64; + DECLARE $b AS Int64; + SELECT $a + $b' \ + --input-format tsv \ + --input-framing newline-delimited \ + --format tsv + ``` + + Command output: + + ```text + 30 + 40 + 83 + ``` + + Or just by passing the input file name to the `--input-file` option: + + ```bash + {{ ydb-cli }} -p quickstart sql \ + -s 'DECLARE $a AS Int64; + DECLARE $b AS Int64; + SELECT $a + $b' \ + --input-file par1.txt \ + --input-format tsv \ + --input-framing newline-delimited \ + --format tsv + ``` + + Command output: + + ```text + 30 + 40 + 83 + ``` + + This output can be passed as input to the next query command. + +{% endlist %} + +#### Streaming processing with joining parameter values from different sources {#example-iterate-union} + +For example, you need to run your query three times with the following sets of values for the `a` and `b` parameters: + +1. `a` = 10, `b` = 100 +2. `a` = 15, `b` = 100 +3. `a` = 35, `b` = 100 + +```bash +echo -e '10\n15\n35' | \ +{{ ydb-cli }} -p quickstart sql \ + -s 'DECLARE $a AS Int64; + DECLARE $b AS Int64; + SELECT $a + $b AS sum1' \ + --param '$b=100' \ + --input-framing newline-delimited \ + --input-param-name a \ + --format json-unicode +``` + +Command output: + +```text +{"sum1":110} +{"sum1":115} +{"sum1":135} +``` + +## Batched streaming processing {#streaming-batch} + +The {{ ydb-short-name }} CLI supports automatic conversion of multiple consecutive parameter sets to a `List<...>`, enabling you to process them in a single request and transaction. As a result, you can achieve a substantial performance gain compared to one-by-one query processing. + +Two batch modes are supported: + +- Full +- Adaptive + +### Full batch mode {#batch-full} + +The `full` mode is a simplified batch mode where the query runs only once, and all the parameter sets received from the input (`stdin` or `--input-file`) are wrapped into a `List<...>`. If the request is too large, you will receive an error. + +Use this batch mode when you want to ensure transaction atomicity by applying all the parameters within a single transaction. + +### Adaptive batch mode {#batch-adaptive} + +In the `adaptive` mode, the input stream is split into multiple transactions, with the batch size automatically determined for each of them. + +In this mode, you can process a broad range of dynamic workloads with unpredictable or infinite amounts of data, as well as workloads with an unpredictable or significantly varying rate of new sets appearing in the input. For example, this scenario is common when sending the output of another command to `stdin` using the `|` operator. + +The adaptive mode solves two key issues of dynamic stream processing: + +1. Limiting the maximum batch size. +2. Limiting the maximum data processing delay. + +### Syntax {#batch-syntax} + +To use the batching capabilities, define the `List<...>` or `List>` parameter in the query's `DECLARE` clause, and use the following options: + +| Name | Description | +| --- | --- | +| `--input-batch` | The batch mode applied to parameter sets on `stdin` or `--input-file`.
Available options:
  • `iterative` (default): Executes the query for each parameter set (exactly one execution when `no-framing` is specified for `--input-framing`).
  • `full`: A simplified batch mode where the query runs only once and all the parameter sets received from the input (`stdin` or `--input-file`) are wrapped into a `List<...>`.
  • `adaptive`: Executes the query with a JSON list of parameter sets whenever the number of sets reaches `--input-batch-max-rows` or the waiting time reaches `--input-batch-max-delay`.
| + +In the adaptive batch mode, you can use the following additional parameters: + +| Name | Description | +| --- | --- | +| `--input-batch-max-rows` | The maximum number of parameter sets per batch in the `adaptive` batch mode. The next batch will be sent with the query if the number of parameter sets reaches the specified limit. When set to `0`, there is no limit.

Default value: `1000`.

Parameter values are sent to each query execution without streaming, so the total size per gRPC request that includes the parameter values has an upper limit of about 5 MB. | +| `--input-batch-max-delay` | The maximum delay before submitting a received parameter set for processing in the `adaptive` batch mode. The value is specified as a number with a time unit: `s` (seconds), `ms` (milliseconds), `m` (minutes), etc. Default value: `1s` (1 second).

The {{ ydb-short-name }} CLI starts a timer when it receives the first set of parameters for the batch from the input and sends the accumulated batch for execution once the timer expires. This parameter enables efficient batching when the arrival rate of new parameter sets is unpredictable. | + +### Examples: Full batch processing {#example-batch-full} + +```bash +echo -e '{"a":10,"b":20}\n{"a":15,"b":25}\n{"a":35,"b":48}' | \ +{{ ydb-cli }} -p quickstart sql \ + -s 'DECLARE $x AS List>; + SELECT ListLength($x), $x' \ + --input-framing newline-delimited \ + --input-param-name x \ + --input-batch full +``` + +Command output: + +```text +┌─────────┬───────────────────────────────────────────────────┐ +| column0 | column1 | +├─────────┼───────────────────────────────────────────────────┤ +| 3 | [{"a":10,"b":20},{"a":15,"b":25},{"a":35,"b":48}] | +└─────────┴───────────────────────────────────────────────────┘ +``` + +### Examples: Adaptive batch processing {#example-batch-adaptive} + +#### Limiting the maximum data processing delay {#example-adaptive-delay} + +This example demonstrates adaptive batching triggered by a processing delay. In the first line of the command below, we generate 1,000 rows with a delay of 0.2 seconds on `stdout` and pipe them to `stdin` for the `ydb sql` query execution command. The query execution command displays the parameter batches in each subsequent query call. + +```bash +for i in $(seq 1 1000); do echo "Line$i"; sleep 0.2; done | \ +{{ ydb-cli }} -p quickstart sql \ + -s 'DECLARE $x AS List; + SELECT ListLength($x), $x' \ + --input-framing newline-delimited \ + --input-format raw \ + --input-param-name x \ + --input-batch adaptive +``` + +Command output (the actual values may differ): + +```text +┌─────────┬────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +| column0 | column1 | +├─────────┼────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ +| 14 | ["Line1","Line2","Line3","Line4","Line5","Line6","Line7","Line8","Line9","Line10","Line11","Line12","Line13","Line14"] | +└─────────┴────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ +┌─────────┬─────────────────────────────────────────────────────────┐ +| column0 | column1 | +├─────────┼─────────────────────────────────────────────────────────┤ +| 6 | ["Line15","Line16","Line17","Line18","Line19","Line20"] | +└─────────┴─────────────────────────────────────────────────────────┘ +┌─────────┬─────────────────────────────────────────────────────────┐ +| column0 | column1 | +├─────────┼─────────────────────────────────────────────────────────┤ +| 6 | ["Line21","Line22","Line23","Line24","Line25","Line26"] | +└─────────┴─────────────────────────────────────────────────────────┘ +^C +``` + +The first batch includes all the rows accumulated at the input while the database connection was being established, which is why it is larger than the subsequent ones. + +You can terminate the command by pressing Ctrl+C or wait 200 seconds until the input generation is finished. + +#### Limit on the number of records {#example-adaptive-limit} + +This example demonstrates adaptive batching triggered by the number of parameter sets. In the first line of the command below, we generate 200 rows. The command displays parameter batches in each subsequent query call, applying the specified limit `--input-batch-max-rows` of 20 (the default limit is 1,000). + +This example also demonstrates the option to join parameters from different sources and generate JSON as output. + +```bash +for i in $(seq 1 200); do echo "Line$i"; done | \ +{{ ydb-cli }} -p quickstart sql \ + -s 'DECLARE $x AS List; + DECLARE $p2 AS Int64; + SELECT ListLength($x) AS count, $p2 AS p2, $x AS items' \ + --input-framing newline-delimited \ + --input-format raw \ + --input-param-name x \ + --input-batch adaptive \ + --input-batch-max-rows 20 \ + --param '$p2=10' \ + --format json-unicode +``` + +Command output: + +```text +{"count":20,"p2":10,"items":["Line1","Line2","Line3","Line4","Line5","Line6","Line7","Line8","Line9","Line10","Line11","Line12","Line13","Line14","Line15","Line16","Line17","Line18","Line19","Line20"]} +{"count":20,"p2":10,"items":["Line21","Line22","Line23","Line24","Line25","Line26","Line27","Line28","Line29","Line30","Line31","Line32","Line33","Line34","Line35","Line36","Line37","Line38","Line39","Line40"]} +... +{"count":20,"p2":10,"items":["Line161","Line162","Line163","Line164","Line165","Line166","Line167","Line168","Line169","Line170","Line171","Line172","Line173","Line174","Line175","Line176","Line177","Line178","Line179","Line180"]} +{"count":20,"p2":10,"items":["Line181","Line182","Line183","Line184","Line185","Line186","Line187","Line188","Line189","Line190","Line191","Line192","Line193","Line194","Line195","Line196","Line197","Line198","Line199","Line200"]} +``` + +#### Deleting multiple records from a {{ ydb-short-name }} table based on primary keys {#example-adaptive-delete-pk} + +If you attempt to delete a large number of rows from a substantial table using a simple `DELETE FROM large_table WHERE id > 10;` statement, you may encounter an error due to exceeding the transaction record limit. This example shows how to delete an unlimited number of records from {{ ydb-short-name }} tables without breaching this limitation. + +Let's create a test table: + +```bash +{{ ydb-cli }} -p quickstart sql -s 'CREATE TABLE test_delete_1(id UInt64 NOT NULL, PRIMARY KEY (id))' +``` + +Add 100,000 records to it: + +```bash +for i in $(seq 1 100000); do echo "$i"; done | \ +{{ ydb-cli }} -p quickstart import file csv -p test_delete_1 +``` + +Delete all records with `id` greater than 10: + +```bash +{{ ydb-cli }} -p quickstart sql \ + -s 'SELECT t.id FROM test_delete_1 AS t WHERE t.id > 10' \ + --format json-unicode | \ +{{ ydb-cli }} -p quickstart sql \ + -s 'DECLARE $lines AS List>; + DELETE FROM test_delete_1 WHERE id IN (SELECT tl.id FROM AS_TABLE($lines) AS tl)' \ + --input-framing newline-delimited \ + --input-param-name lines \ + --input-batch adaptive \ + --input-batch-max-rows 10000 +``` + +#### Processing messages read from a topic {#example-adaptive-pipeline-from-topic} + +Examples of processing messages read from a topic are provided in [{#T}](topic-pipeline.md#example-read-to-yql-param). + +## See also {#see-also} + +* [Parameterized queries in {{ ydb-short-name }} SDK](../ydb-sdk/parameterized_queries.md) diff --git a/ydb/docs/en/core/yql/reference/syntax/delete.md b/ydb/docs/en/core/yql/reference/syntax/delete.md index 335c9be619da..ff182260bebf 100644 --- a/ydb/docs/en/core/yql/reference/syntax/delete.md +++ b/ydb/docs/en/core/yql/reference/syntax/delete.md @@ -1,16 +1,6 @@ # DELETE FROM -{% if oss == true and backend_name == "YDB" %} - -{% note warning %} - -Supported only for [row-oriented](../../../concepts/datamodel/table.md#row-oriented-tables) tables. Support for [column-oriented](../../../concepts/datamodel/table.md#column-oriented-tables) tables is currently under development. - -Instead of using `DELETE FROM` to delete data from colum-oriented tables, you can use the mechanism of deleting rows by time — [TTL](../../../concepts/ttl.md). TTL can be set when [creating](create_table/index.md) the table via `CREATE TABLE` or [modified](alter_table/index.md) later via `ALTER TABLE`. - -{% endnote %} - -{% endif %} +{% include [column-and-row-tables-in-read-only-tx](../../../_includes/limitation-column-row-in-read-only-tx-warn.md) %} Deletes rows that match the `WHERE` clause, from the table.{% if feature_mapreduce %} The table is searched by name in the database specified by the [USE](use.md) operator.{% endif %} diff --git a/ydb/docs/en/core/yql/reference/syntax/insert_into.md b/ydb/docs/en/core/yql/reference/syntax/insert_into.md index 8ca50f196e5c..d7657244f4ce 100644 --- a/ydb/docs/en/core/yql/reference/syntax/insert_into.md +++ b/ydb/docs/en/core/yql/reference/syntax/insert_into.md @@ -1,26 +1,8 @@ # INSERT INTO -{% if oss == true and backend_name == "YDB" %} +{% include [column-and-row-tables-in-read-only-tx](../../../_includes/limitation-column-row-in-read-only-tx-warn.md) %} -{% note warning %} - -Supported only for [row-oriented](../../../concepts/datamodel/table.md#row-oriented-tables) tables. Support for [column-oriented](../../../concepts/datamodel/table.md#column-oriented-tables) tables is currently under development. - -{% if oss %} - -Available methods for loading data into columnar tables: - -* [{{ ydb-short-name }} CLI](../../../reference/ydb-cli/export-import/import-file.md) -* [Bulk data upsert](../../../recipes/ydb-sdk/bulk-upsert.md) -* [Yandex Data Transfer](https://yandex.cloud/ru/services/data-transfer) - -{% endif %} - -{% endnote %} - -{% endif %} - -{% if select_command != "SELECT STREAM" %} Adds rows to the table. {% if feature_bulk_tables %} If the target table already exists and is not sorted, the operation `INSERT INTO` adds rows at the end of the table. In the case of a sorted table, YQL tries to preserve sorting by running a sorted merge. {% endif %}{% if feature_map_tables %} If you try to insert a row into a table with an existing primary key value, the operation fails with the `PRECONDITION_FAILED` error code and the `Operation aborted due to constraint violation: insert_pk` message returned.{% endif %} +{% if select_command != "SELECT STREAM" %} Adds rows to the table.{% if feature_bulk_tables %} If the target table already exists and is not sorted, the operation `INSERT INTO` adds rows at the end of the table. In the case of a sorted table, YQL tries to preserve sorting by running a sorted merge. {% endif %}{% if feature_map_tables %} If you try to insert a row into a table with an existing primary key value, the operation fails with the `PRECONDITION_FAILED` error code and the `Operation aborted due to constraint violation: insert_pk` message returned.{% endif %} {% if feature_mapreduce %}The table is searched by name in the database specified by the [USE](use.md) operator.{% endif %} diff --git a/ydb/docs/en/core/yql/reference/syntax/replace_into.md b/ydb/docs/en/core/yql/reference/syntax/replace_into.md index a7235c96b7ff..149188a934cd 100644 --- a/ydb/docs/en/core/yql/reference/syntax/replace_into.md +++ b/ydb/docs/en/core/yql/reference/syntax/replace_into.md @@ -1,24 +1,6 @@ # REPLACE INTO -{% if oss == true and backend_name == "YDB" %} - -{% note warning %} - -Supported only for [row-oriented](../../../concepts/datamodel/table.md#row-oriented-tables) tables. Support for [column-oriented](../../../concepts/datamodel/table.md#column-oriented-tables) tables is currently under development. - -{% if oss %} - -Available methods for loading data into columnar tables: - -* [{{ ydb-short-name }} CLI](../../../reference/ydb-cli/export-import/import-file.md) -* [Bulk data upsert](../../../recipes/ydb-sdk/bulk-upsert.md) -* [Yandex Data Transfer](https://yandex.cloud/ru/services/data-transfer) - -{% endif %} - -{% endnote %} - -{% endif %} +{% include [column-and-row-tables-in-read-only-tx](../../../_includes/limitation-column-row-in-read-only-tx-warn.md) %} Saves data to a table, overwriting the rows based on the primary key.{% if feature_mapreduce %} The table is searched by name in the database specified by the [USE](use.md) operator.{% endif %} If the given primary key is missing, a new row is added to the table. If the given `PRIMARY_KEY` exists, the row is overwritten. The values of columns not involved in the operation are replaced by their default values. diff --git a/ydb/docs/en/core/yql/reference/syntax/update.md b/ydb/docs/en/core/yql/reference/syntax/update.md index a970a895e6a2..69ddb07ff878 100644 --- a/ydb/docs/en/core/yql/reference/syntax/update.md +++ b/ydb/docs/en/core/yql/reference/syntax/update.md @@ -1,24 +1,6 @@ # UPDATE -{% if oss == true and backend_name == "YDB" %} - -{% note warning %} - -Supported only for [row-oriented](../../../concepts/datamodel/table.md#row-oriented-tables) tables. Support for [column-oriented](../../../concepts/datamodel/table.md#column-oriented-tables) tables is currently under development. - -{% if oss %} - -Available methods for loading data into columnar tables: - -* [{{ ydb-short-name }} CLI](../../../reference/ydb-cli/export-import/import-file.md) -* [Bulk data upsert](../../../recipes/ydb-sdk/bulk-upsert.md) -* [Yandex Data Transfer](https://yandex.cloud/ru/services/data-transfer) - -{% endif %} - -{% endnote %} - -{% endif %} +{% include [column-and-row-tables-in-read-only-tx](../../../_includes/limitation-column-row-in-read-only-tx-warn.md) %} Updates the data in the table.{% if feature_mapreduce %} The table is searched by name in the database specified by the [USE](use.md) operator.{% endif %} After the `SET` keyword, enter the columns where you want to update values and the new values themselves. The list of rows is defined by the `WHERE` clause. If `WHERE` is omitted, the updates are applied to all the rows of the table. diff --git a/ydb/docs/en/core/yql/reference/syntax/upsert_into.md b/ydb/docs/en/core/yql/reference/syntax/upsert_into.md index 844e8063ea1c..240dd3be80d5 100644 --- a/ydb/docs/en/core/yql/reference/syntax/upsert_into.md +++ b/ydb/docs/en/core/yql/reference/syntax/upsert_into.md @@ -1,24 +1,6 @@ # UPSERT INTO -{% if oss == true and backend_name == "YDB" %} - -{% note warning %} - -Supported only for [row-oriented](../../../concepts/datamodel/table.md#row-oriented-tables) tables. Support for [column-oriented](../../../concepts/datamodel/table.md#column-oriented-tables) tables is currently under development. - -{% if oss %} - -Available methods for loading data into columnar tables: - -* [{{ ydb-short-name }} CLI](../../../reference/ydb-cli/export-import/import-file.md) -* [Bulk data upsert](../../../recipes/ydb-sdk/bulk-upsert.md) -* [Yandex Data Transfer](https://yandex.cloud/ru/services/data-transfer) - -{% endif %} - -{% endnote %} - -{% endif %} +{% include [column-and-row-tables-in-read-only-tx](../../../_includes/limitation-column-row-in-read-only-tx-warn.md) %} UPSERT (which stands for UPDATE or INSERT) updates or inserts multiple rows to a table based on a comparison by the primary key. Missing rows are added. For the existing rows, the values of the specified columns are updated, but the values of the other columns are preserved. diff --git a/ydb/docs/ru/core/_includes/limitation-column-row-in-read-only-tx-warn.md b/ydb/docs/ru/core/_includes/limitation-column-row-in-read-only-tx-warn.md new file mode 100644 index 000000000000..be17501ecb1c --- /dev/null +++ b/ydb/docs/ru/core/_includes/limitation-column-row-in-read-only-tx-warn.md @@ -0,0 +1,5 @@ +{% note warning %} + +{% include [column-and-row-tables-in-read-only-tx](./limitation-column-row-in-read-only-tx.md) %} + +{% endnote %} \ No newline at end of file diff --git a/ydb/docs/ru/core/_includes/limitation-column-row-in-read-only-tx.md b/ydb/docs/ru/core/_includes/limitation-column-row-in-read-only-tx.md new file mode 100644 index 000000000000..eaf11b11ce86 --- /dev/null +++ b/ydb/docs/ru/core/_includes/limitation-column-row-in-read-only-tx.md @@ -0,0 +1,3 @@ +В настоящее время одновременное использование [колоночных](../concepts/glossary.md#column-oriented-table) и [строковых](../concepts/glossary.md#row-oriented-table) таблиц возможно только в Read-Only транзакциях. Поддержка транзакций с возможностью записи при одновременном использовании строковых и колоночных таблиц находится в разработке. + +Если попытаться выполнить операцию записи в транзакции, в которой задействованы и колоночные, и строковые таблицы, транзакция завершится с ошибкой: `Write transactions between column and row tables are disabled at current time`. diff --git a/ydb/docs/ru/core/concepts/_includes/transactions.md b/ydb/docs/ru/core/concepts/_includes/transactions.md index 167f43e5a3a4..647b4dec5fb8 100644 --- a/ydb/docs/ru/core/concepts/_includes/transactions.md +++ b/ydb/docs/ru/core/concepts/_includes/transactions.md @@ -55,6 +55,16 @@ ## Транзакции с участием топиков и таблиц {#topic-table-transactions} +{% note warning %} + +{% include [not_allow_for_olap](../../_includes/not_allow_for_olap_text.md) %} + +{% endnote %} + {{ ydb-short-name }} поддерживает транзакции с участием [строковых таблиц](../glossary.md#row-oriented-table) и/или топиков. Таким образом, можно транзакционно перекладывать данные из таблиц в топики и в обратном направлении, а также между топиками, чтобы данные не терялись и не дублировались даже в случае непредвиденных обстоятельств. -Подробнее о транзакционных операциях при работе с топиками см. в [{#T}](../topic.md#topic-transactions) и [{#T}](../../reference/ydb-sdk/topic.md). \ No newline at end of file +Подробнее о транзакционных операциях при работе с топиками см. в [{#T}](../topic.md#topic-transactions) и [{#T}](../../reference/ydb-sdk/topic.md). + +## Транзакции с участием строковых и столбцовых таблиц {#mixed-transactions} + +{% include [limitation](../../_includes/limitation-column-row-in-read-only-tx.md) %} diff --git a/ydb/docs/ru/core/concepts/transactions.md b/ydb/docs/ru/core/concepts/transactions.md index 6f13c8538067..6c10a41f3350 100644 --- a/ydb/docs/ru/core/concepts/transactions.md +++ b/ydb/docs/ru/core/concepts/transactions.md @@ -1 +1 @@ -{% include [transactions.md](_includes/transactions.md) %} \ No newline at end of file +{% include [transactions.md](./_includes/transactions.md) %} \ No newline at end of file diff --git a/ydb/docs/ru/core/dev/yql-tutorial/fill_tables_with_data.md b/ydb/docs/ru/core/dev/yql-tutorial/fill_tables_with_data.md index fbbca78bb9c2..0b50ecae3b56 100755 --- a/ydb/docs/ru/core/dev/yql-tutorial/fill_tables_with_data.md +++ b/ydb/docs/ru/core/dev/yql-tutorial/fill_tables_with_data.md @@ -1,14 +1,6 @@ # Добавление данных в таблицы -{% note warning %} - -{% include [not_allow_for_olap](../../_includes/not_allow_for_olap_text.md) %} - -{% include [not_allow_for_olap](../../_includes/ways_add_data_to_olap.md) %} - -{% endnote %} - -Наполните данными [созданные](create_demo_tables.md) ранее строковые таблицы с помощью конструкции [REPLACE INTO](../../yql/reference/syntax/replace_into.md). +Наполните данными [созданные ранее](create_demo_tables.md) таблицы с помощью конструкции [REPLACE INTO](../../yql/reference/syntax/replace_into.md). ```yql REPLACE INTO series (series_id, title, release_date, series_info) diff --git a/ydb/docs/ru/core/dev/yql-tutorial/insert_into.md b/ydb/docs/ru/core/dev/yql-tutorial/insert_into.md index bbd478df3fbd..96d73454e81a 100755 --- a/ydb/docs/ru/core/dev/yql-tutorial/insert_into.md +++ b/ydb/docs/ru/core/dev/yql-tutorial/insert_into.md @@ -1,14 +1,8 @@ # Вставка данных с помощью INSERT -{% note warning %} +{% include [column-and-row-tables-in-read-only-tx](../../_includes/limitation-column-row-in-read-only-tx-warn.md) %} -{% include [not_allow_for_olap](../../_includes/not_allow_for_olap_text.md) %} - -{% include [not_allow_for_olap](../../_includes/ways_add_data_to_olap.md) %} - -{% endnote %} - -Добавьте данные в строковую таблицу с помощью конструкции [INSERT INTO](../../yql/reference/syntax/insert_into.md). +Добавьте данные в таблицу с помощью конструкции [INSERT INTO](../../yql/reference/syntax/insert_into.md). {% include [yql-reference-prerequisites](_includes/yql_tutorial_prerequisites.md) %} diff --git a/ydb/docs/ru/core/dev/yql-tutorial/replace_into.md b/ydb/docs/ru/core/dev/yql-tutorial/replace_into.md index cb635ac293cb..431cfcc71010 100755 --- a/ydb/docs/ru/core/dev/yql-tutorial/replace_into.md +++ b/ydb/docs/ru/core/dev/yql-tutorial/replace_into.md @@ -1,14 +1,8 @@ # Вставка и модификация данных с помощью REPLACE -{% note warning %} +{% include [column-and-row-tables-in-read-only-tx](../../_includes/limitation-column-row-in-read-only-tx-warn.md) %} -{% include [not_allow_for_olap](../../_includes/not_allow_for_olap_text.md) %} - -{% include [not_allow_for_olap](../../_includes/ways_add_data_to_olap.md) %} - -{% endnote %} - -Добавьте данные в строковые таблицы с помощью конструкции [REPLACE INTO](../../yql/reference/syntax/replace_into.md). +Добавьте новые данные в таблицы с одновременным обновлением уже существующих данных с помощью конструкции [REPLACE INTO](../../yql/reference/syntax/replace_into.md). {% include [yql-reference-prerequisites](_includes/yql_tutorial_prerequisites.md) %} diff --git a/ydb/docs/ru/core/reference/ydb-cli/parameterized-queries-cli.md b/ydb/docs/ru/core/reference/ydb-cli/parameterized-queries-cli.md index 74567e0a49bd..b6c5b0083809 100644 --- a/ydb/docs/ru/core/reference/ydb-cli/parameterized-queries-cli.md +++ b/ydb/docs/ru/core/reference/ydb-cli/parameterized-queries-cli.md @@ -485,11 +485,9 @@ for i in $(seq 1 200);do echo "Line$i";done | \ #### Удаление множества записей из строковой таблицы {{ ydb-short-name }} по первичным ключам {#example-adaptive-delete-pk} -{% include [not_allow_for_olap_note](../../_includes/not_allow_for_olap_note.md) %} +Данный пример показывает, как можно удалять неограниченное количество записей из строковых таблиц {{ ydb-short-name }}, не рискуя превысить ограничения на количество записей в транзакции. -Данный пример показывает как можно удалять неограниченное количество записей из строковых таблиц {{ ydb-short-name }}, не рискуя превысить ограничения на количество записей в транзакции. - -Создадим тестовую строковую таблицу: +Создайте тестовую строковую таблицу: ```bash {{ ydb-cli }} -p quickstart yql -s 'create table test_delete_1( id UInt64 not null, primary key (id))' diff --git a/ydb/docs/ru/core/reference/ydb-cli/parameterized-query-execution.md b/ydb/docs/ru/core/reference/ydb-cli/parameterized-query-execution.md new file mode 100644 index 000000000000..7d942845b6a4 --- /dev/null +++ b/ydb/docs/ru/core/reference/ydb-cli/parameterized-query-execution.md @@ -0,0 +1,591 @@ +# Выполнение параметризованных запросов + +## Обзор + +{{ ydb-short-name }} CLI поддерживает исполнение [параметризованных запросов](https://en.wikipedia.org/wiki/Prepared_statement). Для работы с параметрами в тексте запроса должны присутствовать их определения [командой YQL `DECLARE`](../../yql/reference/syntax/declare.md). + +Основной инструмент для выполнения параметризованных запросов в {{ ydb-short-name }} CLI — это команда [{{ ydb-cli }} sql](sql.md). + +## Зачем использовать параметризованные запросы? + +Использование параметризованных запросов предоставляет несколько важных преимуществ: + +* **Улучшенная производительность:** Параметризованные запросы значительно повышают производительность при выполнении множества схожих запросов, которые различаются только входными параметрами. Это достигается с помощью [подготовленных запросов](https://en.wikipedia.org/wiki/Prepared_statement). Запрос компилируется один раз и затем кешируется на сервере. Последующие запросы с тем же текстом минуют фазу компиляции и сразу начинают выполняться. + +* **Защита от SQL-инъекций:** Другим важным преимуществом использования параметризованных запросов является защита от [SQL-инъекций](https://en.wikipedia.org/wiki/SQL_injection). Эта функция безопасности гарантирует правильную обработку входных данных, что снижает риск выполнения вредоносного кода. + +## Единичное исполнение запроса {#one-request} + +Эта команда поддерживает передачу параметров через опции командной строки, файл, а также через `stdin`. При передаче параметров через `stdin` или файл поддерживается многократное поточное исполнение запроса с разными значениями параметров и возможностью пакетирования. Для этого в команде [{{ ydb-cli }} sql](sql.md) предназначены следующие параметры: + +| Имя | Описание | +| ---|--- | +| `-p, --param` | Значение одного параметра запроса в формате `$name=value` или `name=value`, где `name` — имя параметра, а `value` — его значение (корректный [JSON value](https://www.json.org/json-ru.html)). | +| `--input-file` | Имя файла в формате [JSON](https://ru.wikipedia.org/wiki/JSON) в кодировке [UTF-8](https://ru.wikipedia.org/wiki/UTF-8), в котором заданы значения параметров, сопоставляемые с параметрами запроса по именам ключей. Может быть использован максимум один файл с параметрами. | +| `--input-format` | Формат представления значений параметров. Действует на все способы их передачи (через параметр команды, файл или `stdin`).
Возможные значения:
  • `json` (по умолчанию): Формат [JSON](https://ru.wikipedia.org/wiki/JSON).
  • `csv` — формат [CSV](https://ru.wikipedia.org/wiki/CSV). По умолчанию имена параметров должны находиться в header'е CSV файла. При единичном исполнении запроса допустима только одна строка в файле, не считая header'a.
  • `tsv` — формат [TSV](https://ru.wikipedia.org/wiki/TSV).
  • `raw`: Входной поток из `stdin` или `--input-file` содержит только значение параметра в виде бинарных данных. Имя параметра должно быть указано опцией `--input-param-name`.
| +| `--input-binary-strings` | Формат кодировния значения параметров с типом «бинарная строка» (`DECLARE $par AS String`). Говорит о том, как должны интерпретироваться бинарные строки из входного потока.
Возможные значения:
  • `unicode`: Каждый байт в бинарной строке, не являющийся печатаемым ASCII-символом (codes 32-126), должен быть закодирован в кодировке [UTF-8](https://ru.wikipedia.org/wiki/UTF-8).
  • `base64`: Бинарные строки представлены в кодировке [Base64](https://ru.wikipedia.org/wiki/Base64). Такая возможность позволяет передавать бинарные данные, декодирование которых из Base64 выполнит {{ ydb-short-name }} CLI.
| + +Если значения указаны для всех параметров, которые не допускают `NULL` (то есть с типом NOT NULL), [в составе оператора `DECLARE`](../../yql/reference/syntax/declare.md), запрос будет выполнен на сервере. Если отсутствует значение хотя бы для одного такого параметра, выполнение команды завершится с ошибкой и сообщением "Не задано значение для параметра". + +### Более специфичные опции для использования входных параметров {#specific-param-options} + +Следующие опции не представлены в выводе `--help`. Их описание можно увидеть только в выводе `-hh`. + +| Имя | Описание | +| ---|--- | +| `--input-framing` | Задает фрейминг для входного потока (`stdin` или `--input-file`). Определяет как входной поток будет разделяться на отдельные наборы параметров.
Возможные значения:
  • `no-framing` (по умолчанию): От входного потока ожидается один набор параметров, запрос исполняется однократно.
  • `newline-delimited`: Символ перевода строки отмечает во входном потоке окончание одного набора параметров, отделяя его от следующего. Набор параметров считается собранным каждый раз при получении во входном потоке символа перевода строки.
| +| `--input-param-name` | Имя параметра, значение которого передано во входной поток. Указывается без символа `$`. Обязательно при использовании формата `raw` в `--input-format`.

При использовании с JSON-форматом входной поток интерпретируется не как JSON-документ, а как JSON value, с передачей значения в параметр с указанным именем. | +| `--input-columns` | Строка с именами колонок, заменяющими header CSV/TSV документа, читаемого из входного потока. При указании опции считается, что header отсутствует. Опция допустима только с форматами CSV и TSV.| +| `--input-skip-rows` | Число строк с начала данных, читаемых со stdin'a, которые нужно пропустить, не включая строку header'a, если она имеется. Опция допустима только с форматами stdin'a CSV и TSV. | +| `--input-batch` | Режим пакетирования значений наборов параметров, получаемых из входного потока (`stdin` или `--input-file`).
Возможные значения:
  • `iterative` (по умолчанию): Пакетирование [выключено](#streaming-iterate). Запрос выполняется для каждого набора параметров (ровно один раз, если в опции `--input-framing` используется `no-framing`)
  • `full`: Полный пакет. Запрос выполнится один раз после завершения чтения входного потока, все полученные наборы параметров заворачиваются в `List<...>`, имя параметра задается опцией `--input-param-name`
  • `adaptive`: Адаптивное пакетирование. Запрос выполняется каждый раз, когда срабатывает ограничение на количество наборов параметров в одном запросе (`--input-batch-max-rows`) или на задержку обработки (`--input-batch-max-delay`). Все полученные к этому моменту наборы параметров заворачиваются в `List<...>`, имя параметра задается опцией `--input-param-name`.
| +| `--input-batch-max-rows` | Максимальное количество наборов параметров в пакете для адаптивного режима пакетирования. Следующий пакет будет отправлен на исполнение вместе с запросом, если количество наборов данных в нем достигло указанного значения. Установка в `0` снимает ограничение.

Значение по умолчанию — `1000`.

Параметры передаются в запрос без стриминга и общий объем одного GRPC-запроса, в который включаются значения параметров, имеет верхнюю границу около 5 МБ. | +| `--input-batch-max-delay` | Максимальная задержка отправки на обработку полученного набора параметров для адаптивного режима пакетирования. Задается в виде числа с размерностью времени - `s` (секунды), `ms` (миллисекунды), `m` (минуты) и т.д. Значение по умолчанию — `1s` (1 секунда).

{{ ydb-short-name }} CLI будет отсчитывать время с момента получения первого набора параметров для пакета и отправит накопившийся пакет на исполнение, как только время превысит указанное значение. Параметр позволяет получить эффективное пакетирование в случае непредсказуемого темпа появления новых наборов параметров на `stdin`. | + +### Примеры {#examples-one-request} + +{% include [ydb-cli-profile](../../_includes/ydb-cli-profile.md) %} + +#### Передача значения одного параметра {#example-simple} + +В командной строке, через опцию `--param`: + +```bash +{{ ydb-cli }} -p quickstart sql -s 'DECLARE $a AS Int64; SELECT $a' --param '$a=10' +``` + +Через файл в формате JSON (который используется по умолчанию): + +```bash +echo '{"a":10}' > p1.json +{{ ydb-cli }} -p quickstart sql -s 'DECLARE $a AS Int64; SELECT $a' --input-file p1.json +``` + +Через `stdin`, передавая JSON-строку как набор из одного параметра: + +```bash +echo '{"a":10}' | {{ ydb-cli }} -p quickstart sql -s 'DECLARE $a AS Int64; SELECT $a' +``` + +Через `stdin`, передавая только значение параметра и задавая имя параметра через опцию `--input-param-name`: + +```bash +echo '10' | {{ ydb-cli }} -p quickstart sql -s 'DECLARE $a AS Int64; SELECT $a' --input-param-name a +``` + +#### Передача значений параметров разных типов из нескольких источников {#example-multisource} + +```bash +# Create a JSON file with fields 'a', 'b', and 'x', where 'x' will be ignored in the query +echo '{ "a":10, "b":"Some text", "x":"Ignore me" }' > p1.json + +# Run the query using ydb-cli, passing in 'a' and 'b' from the input file, and 'c' as a direct parameter +{{ ydb-cli }} -p quickstart sql \ + -s 'DECLARE $a AS Int64; + DECLARE $b AS Utf8; + DECLARE $c AS Int64; + + SELECT $a, $b, $c' \ + --input-file p1.json \ + --param '$c=30' +``` + +Вывод команды: + +```text +┌─────────┬─────────────┬─────────┐ +│ column0 │ column1 │ column2 │ +├─────────┼─────────────┼─────────┤ +│ 10 │ "Some text" │ 30 │ +└─────────┴─────────────┴─────────┘ +``` + +#### Передача бинарных строк в кодировке Base64 {#example-base64} + +```bash +{{ ydb-cli }} -p quickstart sql \ + -s 'DECLARE $a AS String; + SELECT $a' \ + --input-format json \ + --input-binary-strings base64 \ + --param '$a="SGVsbG8sIHdvcmxkCg=="' +``` + +Вывод команды: + +```text +┌──────────────────┐ +| column0 | +├──────────────────┤ +| "Hello, world\n" | +└──────────────────┘ +``` + +#### Прямая передача бинарного контента {#example-raw} + +```bash +curl -Ls http://ydb.tech/docs/en | {{ ydb-cli }} -p quickstart sql \ + -s 'DECLARE $a AS String; + SELECT LEN($a)' \ + --input-format raw \ + --input-param-name a +``` + +Вывод команды (точное количество байт может отличаться): + +```text +┌─────────┐ +| column0 | +├─────────┤ +| 66426 | +└─────────┘ +``` + +#### Передача файла в формате CSV {#example-csv} + +```bash +echo '10,Some text' | {{ ydb-cli }} -p quickstart sql \ + -s 'DECLARE $a AS Int32; + DECLARE $b AS String; + SELECT $a, $b' \ + --input-format csv \ + --input-columns 'a,b' +``` + +Вывод команды: + +```text +┌─────────┬─────────────┐ +| column0 | column1 | +├─────────┼─────────────┤ +| 10 | "Some text" | +└─────────┴─────────────┘ +``` + +## Итеративная потоковая обработка {#streaming-iterate} + +{{ ydb-short-name }} CLI поддерживает возможность многократного исполнения запроса с разными наборами значений параметров, при их передаче через `stdin` **или** входной файл (не одновременно). При этом соединение с базой данных устанавливается однократно, а план исполнения запроса кешируется, что существенно повышает производительность такого подхода по сравнению с отдельными вызовами CLI. + +Для того чтобы воспользоваться этой возможностью, необходимо на вход команды друг за другом передавать разные наборы значений одних и тех параметров, сообщив {{ ydb-short-name }} CLI правило, по которому будет возможно отделить эти наборы друг от друга. + +Запрос выполняется столько раз, сколько наборов значений параметров было получено. Каждый полученный через входной поток (`stdin` или `--input-file`) набор объединяется со значениями параметров, определенными через опции `--param`. Исполнение команды будет завершено после завершения входного потока. Каждый запрос исполняется в своей транзакции. + +Правило отделения наборов параметров друг от друга (фрейминг) дополняет описание формата представления параметров на входном потоке, задаваемое параметром `--input--framing`: + +| Имя | Описание | +| ---|--- | +| `--input-framing` | Задает фрейминг для входного потока (файл или `stdin`).
Возможные значения:
  • `no-framing` (по умолчанию) — на входе ожидается один набор параметров, запрос исполняется однократно после завершения чтения потока.
  • `newline-delimited` — символ перевода строки отмечает на входе окончание одного набора параметров, отделяя его от следующего. Запрос исполняется каждый раз при получении символа перевода строки.
| + +{% note warning %} + +При использовании символа перевода строки в качестве разделителя наборов параметров необходимо гарантировать его отсутствие внутри наборов параметров. Заключение текста в кавычки не делает допустимым перевод строки внутри такого текста. Многострочные JSON-документы не допускаются. + +{% endnote %} + +### Пример {#example-streaming-iterate} + +#### Потоковая обработка нескольких наборов параметров {#example-iterate} + +{% list tabs %} + +- JSON + + Допустим, нам необходимо выполнить запрос трижды, со следующими наборами значений параметров `a` и `b`: + + 1. `a` = 10, `b` = 20 + 2. `a` = 15, `b` = 25 + 3. `a` = 35, `b` = 48 + + Создадим файл, который будет содержать строки с JSON-представлением этих наборов: + + ```bash + echo -e '{"a":10,"b":20}\n{"a":15,"b":25}\n{"a":35,"b":48}' | tee par1.txt + ``` + + Вывод команды: + + ```text + {"a":10,"b":20} + {"a":15,"b":25} + {"a":35,"b":48} + ``` + + Исполним запрос, передав на `stdin` содержимое данного файла, с форматированием вывода в JSON: + + ```bash + cat par1.txt | \ + {{ ydb-cli }} -p quickstart sql \ + -s 'DECLARE $a AS Int64; + DECLARE $b AS Int64; + SELECT $a+$b' \ + --input-framing newline-delimited \ + --format json-unicode + ``` + + Вывод команды: + + ```text + {"column0":30} + {"column0":40} + {"column0":83} + ``` + + Или просто передав имя файла в опцию `--input-file`: + + ```bash + {{ ydb-cli }} -p quickstart sql \ + -s 'DECLARE $a AS Int64; + DECLARE $b AS Int64; + SELECT $a + $b' \ + --input-file par1.txt \ + --input-framing newline-delimited \ + --format json-unicode + ``` + + Вывод команды: + + ```text + {"column0":30} + {"column0":40} + {"column0":83} + ``` + + Полученный в таком формате результат можно использовать для передачи на вход команде исполнения следующего запроса. + +- CSV + + Допустим, нам необходимо выполнить запрос трижды, со следующими наборами значений параметров `a` и `b`: + + 1. `a` = 10, `b` = 20 + 2. `a` = 15, `b` = 25 + 3. `a` = 35, `b` = 48 + + Создадим файл c наборами значений параметров в формате CSV: + + ```bash + echo -e 'a,b\n10,20\n15,25\n35,48' | tee par1.txt + ``` + + Вывод команды: + + ```text + a,b + 10,20 + 15,25 + 35,48 + ``` + + Исполним запрос, передав на `stdin` содержимое данного файла, с форматированием вывода в CSV: + + ```bash + cat par1.txt | \ + {{ ydb-cli }} -p quickstart sql \ + -s 'DECLARE $a AS Int64; + DECLARE $b AS Int64; + SELECT $a + $b' \ + --input-format csv \ + --input-framing newline-delimited \ + --format csv + ``` + + Вывод команды: + + ```text + 30 + 40 + 83 + ``` + + Или просто передав имя файла в опцию `--input-file`: + + ```bash + {{ ydb-cli }} -p quickstart sql \ + -s 'DECLARE $a AS Int64; + DECLARE $b AS Int64; + SELECT $a + $b' \ + --input-file par1.txt \ + --input-format csv \ + --input-framing newline-delimited \ + --format csv + ``` + + Вывод команды: + + ```text + 30 + 40 + 83 + ``` + + Полученный в таком формате результат можно использовать для передачи на вход команде исполнения следующего запроса, задав header данным в CSV формате опцией `--input-columns`. + +- TSV + + Допустим, нам необходимо выполнить запрос трижды, со следующими наборами значений параметров `a` и `b`: + + 1. `a` = 10, `b` = row1 + 2. `a` = 15, `b` = row 2 + 3. `a` = 35, `b` = "row"\n3 + + Создадим файл c наборами значений параметров в формате TSV: + + ```bash + echo -e 'a\tb\n10\t20\n15\t25\n35\t48' | tee par1.txt + ``` + + Вывод команды: + + ```text + a b + 10 20 + 15 25 + 35 48 + ``` + + Исполним запрос, передав на `stdin` содержимое данного файла, с форматированием вывода в TSV: + + ```bash + cat par1.txt | \ + {{ ydb-cli }} -p quickstart sql \ + -s 'DECLARE $a AS Int64; + DECLARE $b AS Utf8; + SELECT $a, $b' \ + --input-framing newline-delimited \ + --input-format tsv \ + --format tsv + ``` + + Вывод команды: + + ```text + 30 + 40 + 83 + ``` + + Или просто передав имя файла в опцию `--input-file`: + + ```bash + {{ ydb-cli }} -p quickstart sql \ + -s 'DECLARE $a AS Int64; + DECLARE $b AS Int64; + SELECT $a + $b' \ + --input-file par1.txt \ + --input-format tsv \ + --input-framing newline-delimited \ + --format tsv + ``` + + Вывод команды: + + ```text + 30 + 40 + 83 + ``` + + Полученный в таком формате результат можно использовать для передачи на вход команде исполнения следующего запроса, задав header данным в TSV формате опцией `--input-columns`. + +{% endlist %} + +#### Потоковая обработка с объединением значений параметров из разных источников {#example-iterate-union} + +Допустим, нам необходимо выполнить запрос трижды, со следующими наборами значений параметров `a` и `b`: + +1. `a` = 10, `b` = 100 +2. `a` = 15, `b` = 100 +3. `a` = 35, `b` = 100 + +```bash +echo -e '10\n15\n35' | \ +{{ ydb-cli }} -p quickstart sql \ + -s 'DECLARE $a AS Int64; + DECLARE $b AS Int64; + SELECT $a + $b AS sum1' \ + --param '$b=100' \ + --input-framing newline-delimited \ + --input-param-name a \ + --format json-unicode +``` + +Вывод команды: + +```text +{"sum1":110} +{"sum1":115} +{"sum1":135} +``` + +## Пакетная потоковая обработка {#streaming-batch} + +{{ ydb-short-name }} CLI поддерживает автоматическую конвертацию наборов параметров в `List<...>`, позволяя одним запросом к серверу обработать множество наборов параметров в одной транзакции, что может дополнительно существенно повышать производительность по сравнению с выполнением запросов "по одному". + +Поддерживаются два режима пакетирования: + +- Полный (`full`); +- Адаптивный (`adaptive`). + +### Полный режим пакетирования {#batch-full} + +Полный (`full`) режим является упрощенным вариантом пакетирования, когда запрос выполняется один раз, с заворачиванием в `List<...>` всех полученных с входного потока наборов параметров. Если размер запроса окажется слишком большим, будет выдана ошибка. + +Данный вариант пакетирования необходим в случае, когда необходимо гарантировать атомарность за счет применения всех параметров в одной транзакции. + +### Адаптивный режим пакетирования {#batch-adaptive} + +При работе в адаптивном (`adaptive`) режиме обработка входного потока разбивается на множество транзакций, с автоматическим подбором размера пакета для каждой из них. + +Данный режим позволяет эффективно обрабатывать широкий спектр входной нагрузки, с непредсказуемым или бесконечным количеством данных, а также непредсказуемым или сильно меняющимся темпом их появления на входе. В частности, такой профиль характерен при подаче на `stdin` выхода другой команды через оператор `|`. + +Адаптивный режим решает две основные проблемы обработки динамического потока: + +1. Ограничение максимального размера пакета. +2. Ограничение максимальной задержки обработки данных. + +### Синтаксис {#batch-syntax} + +Для того чтобы воспользоваться возможностью пакетирования, необходимо описать параметр типа `List<...>` или `List>` в секции DECLARE запроса, и выбрать режим следующим параметром: + +| Имя | Описание | +| ---|--- | +| `--input-batch` | Режим пакетирования значений наборов параметров, получаемых из входного потока (`stdin` или `--input-file`).
Возможные значения:
  • `iterative` (по умолчанию): Пакетирование [выключено](#streaming-iterate). Запрос выполняется для каждого набора параметров (ровно один раз, если в опции `--input-framing` используется `no-framing`)
  • `full`: Полный пакет. Запрос выполнится один раз после завершения чтения входного потока, все полученные наборы параметров заворачиваются в `List<...>`, имя параметра задается опцией `--input-param-name`
  • `adaptive`: Адаптивное пакетирование. Запрос выполняется каждый раз, когда срабатывает ограничение на количество наборов параметров в одном запросе (`--input-batch-max-rows`) или на задержку обработки (`--input-batch-max-delay`). Все полученные к этому моменту наборы параметров заворачиваются в `List<...>`, имя параметра задается опцией `--input-param-name`.
| + +В адаптивном режиме пакетирования доступны дополнительные параметры: + +| Имя | Описание | +| ---|--- | +| `--input-batch-max-rows` | Максимальное количество наборов параметров в пакете для адаптивного режима пакетирования. Следующий пакет будет отправлен на исполнение вместе с запросом, если количество наборов данных в нем достигло указанного значения. Установка в `0` снимает ограничение.

Значение по умолчанию — `1000`.

Параметры передаются в запрос без стриминга и общий объем одного GRPC-запроса, в который включаются значения параметров, имеет верхнюю границу около 5 МБ. | +| `--input-batch-max-delay` | Максимальная задержка отправки на обработку полученного набора параметров для адаптивного режима пакетирования. Задается в виде числа с размерностью времени - `s` (секунды), `ms` (миллисекунды), `m` (минуты) и т.д. Значение по умолчанию — `1s` (1 секунда).

{{ ydb-short-name }} CLI будет отсчитывать время с момента получения первого набора параметров для пакета и отправит накопившийся пакет на исполнение, как только время превысит указанное значение. Параметр позволяет получить эффективное пакетирование в случае непредсказуемого темпа появления новых наборов параметров на `stdin`. | + +### Примеры - полная пакетная обработка {#example-batch-full} + +```bash +echo -e '{"a":10,"b":20}\n{"a":15,"b":25}\n{"a":35,"b":48}' | \ +{{ ydb-cli }} -p quickstart sql \ + -s 'DECLARE $x AS List>; + SELECT ListLength($x), $x' \ + --input-framing newline-delimited \ + --input-param-name x \ + --input-batch full +``` + +Вывод команды: + +```text +┌─────────┬───────────────────────────────────────────────────┐ +| column0 | column1 | +├─────────┼───────────────────────────────────────────────────┤ +| 3 | [{"a":10,"b":20},{"a":15,"b":25},{"a":35,"b":48}] | +└─────────┴───────────────────────────────────────────────────┘ +``` + +### Примеры - адаптивная пакетная обработка {#example-batch-adaptive} + +#### Ограничение максимальной задержки обработки {#example-adaptive-delay} + +Для демонстрации работы адаптивного пакетирования со срабатыванием ограничения по задержке обработки в первой строке команды ниже производится генерация 1000 строк с задержкой в 0.2 секунды в `stdout`, которые передаются на `stdin` команде исполнения запроса. Команда исполнения запроса, в свою очередь, отображает пакеты параметров в каждом следующем вызове запроса. + +```bash +for i in $(seq 1 1000); do echo "Line$i"; sleep 0.2; done | \ +{{ ydb-cli }} -p quickstart sql \ + -s 'DECLARE $x AS List; + SELECT ListLength($x), $x' \ + --input-framing newline-delimited \ + --input-format raw \ + --input-param-name x \ + --input-batch adaptive +``` + +Вывод команды (точные значения могут отличаться): + +```text +┌─────────┬────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +| column0 | column1 | +├─────────┼────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ +| 14 | ["Line1","Line2","Line3","Line4","Line5","Line6","Line7","Line8","Line9","Line10","Line11","Line12","Line13","Line14"] | +└─────────┴────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ +┌─────────┬─────────────────────────────────────────────────────────┐ +| column0 | column1 | +├─────────┼─────────────────────────────────────────────────────────┤ +| 6 | ["Line15","Line16","Line17","Line18","Line19","Line20"] | +└─────────┴─────────────────────────────────────────────────────────┘ +┌─────────┬─────────────────────────────────────────────────────────┐ +| column0 | column1 | +├─────────┼─────────────────────────────────────────────────────────┤ +| 6 | ["Line21","Line22","Line23","Line24","Line25","Line26"] | +└─────────┴─────────────────────────────────────────────────────────┘ +^C +``` + +В первый пакет попадают все строки, накопившиеся на входе за время открытия соединения с БД, и поэтому он больше чем последующие. + +Выполнение команды можно прервать по Ctrl+C, или дождаться пока пройдут 200 секунд, в течение которых генерируется вход. + +#### Ограничение по количеству записей {#example-adaptive-limit} + +Для демонстрации работы адаптивного пакетирования со срабатыванием триггера по количеству наборов параметров в первой строке команды ниже производится генерация 200 строк. Команда будет отображать пакеты параметров в каждом следующем вызове запроса, учитывая заданное ограничение `--input-batch-max-rows` равное 20 (по умолчанию 1000). + +В данном примере также показана возможность объединения параметров из разных источников, и формирование JSON на выходе. + +```bash +for i in $(seq 1 200); do echo "Line$i"; done | \ +{{ ydb-cli }} -p quickstart sql \ + -s 'DECLARE $x AS List; + DECLARE $p2 AS Int64; + SELECT ListLength($x) AS count, $p2 AS p2, $x AS items' \ + --input-framing newline-delimited \ + --input-format raw \ + --input-param-name x \ + --input-batch adaptive \ + --input-batch-max-rows 20 \ + --param '$p2=10' \ + --format json-unicode +``` + +Вывод команды: + +```text +{"count":20,"p2":10,"items":["Line1","Line2","Line3","Line4","Line5","Line6","Line7","Line8","Line9","Line10","Line11","Line12","Line13","Line14","Line15","Line16","Line17","Line18","Line19","Line20"]} +{"count":20,"p2":10,"items":["Line21","Line22","Line23","Line24","Line25","Line26","Line27","Line28","Line29","Line30","Line31","Line32","Line33","Line34","Line35","Line36","Line37","Line38","Line39","Line40"]} +... +{"count":20,"p2":10,"items":["Line161","Line162","Line163","Line164","Line165","Line166","Line167","Line168","Line169","Line170","Line171","Line172","Line173","Line174","Line175","Line176","Line177","Line178","Line179","Line180"]} +{"count":20,"p2":10,"items":["Line181","Line182","Line183","Line184","Line185","Line186","Line187","Line188","Line189","Line190","Line191","Line192","Line193","Line194","Line195","Line196","Line197","Line198","Line199","Line200"]} +``` + +#### Удаление множества записей из строковой таблицы {{ ydb-short-name }} по первичным ключам {#example-adaptive-delete-pk} + +Если вы попытаетесь удалить большое количество строк из крупной таблицы с помощью простого запроса `DELETE FROM large_table WHERE id > 10;`, вы можете столкнуться с ошибкой из-за превышения ограничения на количество записей в транзакции. Данный пример показывает, как можно удалять неограниченное количество записей из таблиц {{ ydb-short-name }} без нарушения этого ограничения. +Создадим тестовую строковую таблицу: + +```bash +{{ ydb-cli }} -p quickstart sql -s 'CREATE TABLE test_delete_1(id UInt64 NOT NULL, PRIMARY KEY (id))' +``` + +Занесем в неё 100,000 записей: + +```bash +for i in $(seq 1 100000); do echo "$i";done | \ +{{ ydb-cli }} -p quickstart import file csv -p test_delete_1 +``` + +Удалим все записи со значениями `id` больше 10: + +```bash +{{ ydb-cli }} -p quickstart sql \ + -s 'SELECT t.id FROM test_delete_1 AS t WHERE t.id > 10' \ + --format json-unicode | \ +{{ ydb-cli }} -p quickstart sql \ + -s 'DECLARE $lines AS List>; + DELETE FROM test_delete_1 WHERE id IN (SELECT tl.id FROM AS_TABLE($lines) AS tl)' \ + --input-framing newline-delimited \ + --input-param-name lines \ + --input-batch adaptive \ + --input-batch-max-rows 10000 +``` + +#### Обработка сообщений, считываемых из топика {#example-adaptive-pipeline-from-topic} + +Примеры обработки сообщений, считываемых из топика, приведены в статье [{#T}](topic-pipeline.md#example-read-to-yql-param). + +## См. также {#see-also} + +* [Параметризованные запросы в {{ ydb-short-name }} SDK](../ydb-sdk/parameterized_queries.md) diff --git a/ydb/docs/ru/core/yql/reference/syntax/delete.md b/ydb/docs/ru/core/yql/reference/syntax/delete.md index 30d727530876..0990a33fce97 100644 --- a/ydb/docs/ru/core/yql/reference/syntax/delete.md +++ b/ydb/docs/ru/core/yql/reference/syntax/delete.md @@ -1,19 +1,9 @@ # DELETE FROM -{% if oss == true and backend_name == "YDB" %} +{% include [column-and-row-tables-in-read-only-tx](../../../_includes/limitation-column-row-in-read-only-tx-warn.md) %} -{% note warning %} - -{% include [OLAP_not_allow_text](../../../_includes/not_allow_for_olap_text.md) %} - -Вместо `DELETE FROM` для удаления данных из колоночных таблиц можно воспользоваться механизмом удаления строк по времени — [TTL](../../../concepts/ttl.md). TTL можно задать при [создании](create_table/index.md) таблицы через `CREATE TABLE` или [измененить позже](alter_table/index.md) через `ALTER TABLE`. - -{% endnote %} - -{% endif %} - -Удаляет строки из строковой таблицы, подходящие под условия, заданные в `WHERE`.{% if feature_mapreduce %} Таблица ищется по имени в базе данных, заданной оператором [USE](use.md).{% endif %} +Удаляет строки из таблицы, подходящие под условия, заданные в `WHERE`.{% if feature_mapreduce %} Таблица ищется по имени в базе данных, заданной оператором [USE](use.md).{% endif %} ## Пример diff --git a/ydb/docs/ru/core/yql/reference/syntax/insert_into.md b/ydb/docs/ru/core/yql/reference/syntax/insert_into.md index b2b1030cd4e8..5b2e29b2acc5 100644 --- a/ydb/docs/ru/core/yql/reference/syntax/insert_into.md +++ b/ydb/docs/ru/core/yql/reference/syntax/insert_into.md @@ -1,20 +1,10 @@ # INSERT INTO -{% if oss == true and backend_name == "YDB" %} - -{% note warning %} - -{% include [OLAP_not_allow_text](../../../_includes/not_allow_for_olap_text.md) %} - -{% include [ways_add_data_to_olap](../../../_includes/ways_add_data_to_olap.md) %} - -{% endnote %} - -{% endif %} +{% include [column-and-row-tables-in-read-only-tx](../../../_includes/limitation-column-row-in-read-only-tx-warn.md) %} {% if select_command != "SELECT STREAM" %} -Добавляет строки в {% if oss == true and backend_name == "YDB" %}строковую{% endif %} таблицу. {% if feature_bulk_tables %} Если целевая таблица уже существует и не является сортированной, операция `INSERT INTO` дописывает строки в конец таблицы. В случае сортированной таблицы, YQL пытается сохранить сортированность путем запуска сортированного слияния. {% endif %}{% if feature_map_tables %} При попытке вставить в таблицу строку с уже существующим значением первичного ключа операция завершится ошибкой с кодом `PRECONDITION_FAILED` и текстом `Operation aborted due to constraint violation: insert_pk`.{% endif %} +Добавляет строки в таблицу.{% if feature_bulk_tables %} Если целевая таблица уже существует и не является сортированной, операция `INSERT INTO` дописывает строки в конец таблицы. В случае сортированной таблицы, YQL пытается сохранить сортированность путем запуска сортированного слияния. {% endif %}{% if feature_map_tables %} При попытке вставить в таблицу строку с уже существующим значением первичного ключа операция завершится ошибкой с кодом `PRECONDITION_FAILED` и текстом `Operation aborted due to constraint violation: insert_pk`.{% endif %} {% if feature_mapreduce %}Таблица по имени ищется в базе данных, заданной оператором [USE](use.md).{% endif %} diff --git a/ydb/docs/ru/core/yql/reference/syntax/replace_into.md b/ydb/docs/ru/core/yql/reference/syntax/replace_into.md index 6426dad9f108..1ea9be42ec7a 100644 --- a/ydb/docs/ru/core/yql/reference/syntax/replace_into.md +++ b/ydb/docs/ru/core/yql/reference/syntax/replace_into.md @@ -1,18 +1,8 @@ # REPLACE INTO -{% if oss == true and backend_name == "YDB" %} +{% include [column-and-row-tables-in-read-only-tx](../../../_includes/limitation-column-row-in-read-only-tx-warn.md) %} -{% note warning %} - -{% include [OLAP_not_allow_text](../../../_includes/not_allow_for_olap_text.md) %} - -{% include [ways_add_data_to_olap](../../../_includes/ways_add_data_to_olap.md) %} - -{% endnote %} - -{% endif %} - -В отличие от [`INSERT INTO`](insert_into.md) и [`UPDATE`](update.md), запросы [`UPSERT INTO`](upsert_into.md) и `REPLACE INTO` не требуют предварительного чтения данных, поэтому выполняются быстрее. `REPLACE INTO` сохраняет данные в {% if backend_name == "YDB" and oss == true %}строковую таблицу{% else %}таблицу{% endif %} с перезаписью строк по первичному ключу.{% if feature_mapreduce %} Таблица по имени ищется в базе данных, заданной оператором [USE](use.md).{% endif %} Если заданный первичный ключ отсутствует, в таблицу будет добавлена новая строка. Если задан существующий `PRIMARY_KEY`, строка будет перезаписана. При этом значения столбцов, не участвующих в операции, заменяются на значения по умолчанию. +В отличие от [`INSERT INTO`](insert_into.md) и [`UPDATE`](update.md), запросы [`UPSERT INTO`](upsert_into.md) и `REPLACE INTO` не требуют предварительного чтения данных, поэтому выполняются быстрее. `REPLACE INTO` сохраняет данные в таблицу с перезаписью строк по первичному ключу.{% if feature_mapreduce %} Таблица ищется по имени в базе данных, заданной оператором [USE](use.md).{% endif %} Если заданный первичный ключ отсутствует, в таблицу будет добавлена новая строка. Если задан существующий первичный ключ, строка будет перезаписана. При этом значения столбцов, не определенных в операции `REPLACE INTO`, заменяются на значения по умолчанию. ## Примеры diff --git a/ydb/docs/ru/core/yql/reference/syntax/update.md b/ydb/docs/ru/core/yql/reference/syntax/update.md index dc5583eb5efc..2d646d14bde7 100644 --- a/ydb/docs/ru/core/yql/reference/syntax/update.md +++ b/ydb/docs/ru/core/yql/reference/syntax/update.md @@ -1,24 +1,12 @@ # UPDATE -{% if oss == true and backend_name == "YDB" %} +{% include [column-and-row-tables-in-read-only-tx](../../../_includes/limitation-column-row-in-read-only-tx-warn.md) %} -{% note warning %} - -{% include [OLAP_not_allow_text](../../../_includes/not_allow_for_olap_text.md) %} - -{% include [ways_add_data_to_olap.md](../../../_includes/ways_add_data_to_olap.md) %} - -{% endnote %} - -{% endif %} +Изменяет данные в таблице.{% if feature_mapreduce %} Таблица ищется по имени в базе данных, заданной оператором [USE](use.md).{% endif %} После ключевого слова `SET` через запятую указываются столбцы, значение которых необходимо заменить, и сами новые значения. Список обновляемых строк задается с помощью условия `WHERE`. Если условие `WHERE` отсутствует, изменения будут применены ко всем строкам таблицы. `UPDATE` не может менять значение колонок, входящих в состав первичного ключа. -Изменяет данные в строковой таблице.{% if feature_mapreduce %} Таблица по имени ищется в базе данных, заданной оператором [USE](use.md).{% endif %} После ключевого слова `SET` указываются столбцы, значение которых необходимо заменить, и сами новые значения. Список строк задается с помощью условия `WHERE`. Если `WHERE` отсутствует, изменения будут применены ко всем строкам таблицы. - -`UPDATE` не может менять значение `PRIMARY_KEY`. - ## Пример ```yql diff --git a/ydb/docs/ru/core/yql/reference/syntax/upsert_into.md b/ydb/docs/ru/core/yql/reference/syntax/upsert_into.md index 7695ee3e0a70..d30bb2a598d2 100644 --- a/ydb/docs/ru/core/yql/reference/syntax/upsert_into.md +++ b/ydb/docs/ru/core/yql/reference/syntax/upsert_into.md @@ -1,19 +1,8 @@ - # UPSERT INTO -{% if oss == true and backend_name == "YDB" %} - -{% note warning %} - -{% include [OLAP_not_allow_text](../../../_includes/not_allow_for_olap_text.md) %} - -{% include [ways_add_data_to_olap](../../../_includes/ways_add_data_to_olap.md) %} - -{% endnote %} - -{% endif %} +{% include [column-and-row-tables-in-read-only-tx](../../../_includes/limitation-column-row-in-read-only-tx-warn.md) %} -UPSERT (расшифровывается как UPDATE or INSERT) обновляет или добавляет множество строк в строковой таблице на основании сравнения по первичному ключу. Отсутствующие строки добавляются. В присутствующих строках обновляются значения заданных столбцов, значения остальных столбцов остаются неизменными. +UPSERT (расшифровывается как UPDATE or INSERT) обновляет или добавляет множество строк в таблице на основании сравнения по первичному ключу. Отсутствующие строки добавляются. В присутствующих строках обновляются значения заданных столбцов, значения остальных столбцов остаются неизменными. {% if feature_mapreduce %} From 3d8aed30a6f08de4416a4dc0fef464096410eae6 Mon Sep 17 00:00:00 2001 From: Anton Bobkov Date: Fri, 12 Sep 2025 19:28:17 +0300 Subject: [PATCH 2/2] Deleted accidentally added files --- .../ydb-cli/parameterized-query-execution.md | 594 ------------------ .../ydb-cli/parameterized-query-execution.md | 591 ----------------- 2 files changed, 1185 deletions(-) delete mode 100644 ydb/docs/en/core/reference/ydb-cli/parameterized-query-execution.md delete mode 100644 ydb/docs/ru/core/reference/ydb-cli/parameterized-query-execution.md diff --git a/ydb/docs/en/core/reference/ydb-cli/parameterized-query-execution.md b/ydb/docs/en/core/reference/ydb-cli/parameterized-query-execution.md deleted file mode 100644 index b02da602afaf..000000000000 --- a/ydb/docs/en/core/reference/ydb-cli/parameterized-query-execution.md +++ /dev/null @@ -1,594 +0,0 @@ -# Running parameterized queries - -## Overview - -{{ ydb-short-name }} CLI can execute parameterized queries. To use parameters, you need to declare them using [the YQL `DECLARE` command](../../yql/reference/syntax/declare.md) in your query text. - -The preferred way to run parameterized queries in {{ ydb-short-name }} CLI is to use the [`ydb sql`](sql.md) command. - -Parameter values can be set via the command-line arguments, uploaded from [JSON](https://en.wikipedia.org/wiki/JSON) files, and read from `stdin` in binary or JSON format. Binary data can be encoded as base64 or UTF-8. While reading from `stdin` or a file, you can stream multiple parameter values, triggering multiple query executions with batching options. - -## Why use parameterized queries? - -Using parameterized queries offers several key advantages: - -* **Enhanced Performance:** Parameterized queries significantly boost performance when executing multiple similar queries that differ only in input parameters. This is achieved through the use of [prepared statements](https://en.wikipedia.org/wiki/Prepared_statement). The query is compiled once and then cached on the server. Subsequent requests with the same query text bypass the compilation phase, allowing for immediate execution. - -* **Protection Against SQL Injection:** Another critical benefit of using parameterized queries is the protection they offer against [SQL injection](https://en.wikipedia.org/wiki/SQL_injection) attacks. This security feature ensures that the input parameters are appropriately handled, mitigating the risk of malicious code execution. - -## Executing a single query {#one-request} - -To provide parameters for a single query execution, you can use the command-line arguments, JSON files, or `stdin`, using the following {{ ydb-short-name }} CLI options: - -| Name | Description | -| --- | --- | -| `-p, --param` | The value of a single query parameter in the `name=value` or `$name=value` format, where `name` is the parameter name and `value` is its value (a valid [JSON value](https://www.json.org/json-en.html)). This option can be specified multiple times.

All specified parameters must be declared in the query using the [DECLARE operator](../../yql/reference/syntax/declare.md). Otherwise, you will receive the "Query does not contain parameter" error. If you specify the same parameter multiple times, you will receive the "Parameter value found in more than one source" error.

Depending on your operating system, you might need to escape the `$` character or enclose your expression in single quotes (`'`). | -| `--input-file` | The name of a file in [JSON](https://en.wikipedia.org/wiki/JSON) format and [UTF-8](https://en.wikipedia.org/wiki/UTF-8) encoding that contains parameter values matched against the query parameters by key names. Only one input file can be used.

If values for the same parameter are found in multiple files or set by the `--param` command-line option, you will receive the "Parameter value found in more than one source" error.

Keys that are present in the file but not declared in the query will be ignored without an error message. | -| `--input-format` | The format of parameter values applied to all sources of parameters (command line, file, or `stdin`).
Available options:
  • `json` (default): JSON format.
  • `csv`: [CSV](https://en.wikipedia.org/wiki/Comma-separated_values) format.
  • `tsv`: [TSV](https://en.wikipedia.org/wiki/Tab-separated_values) format.
  • `raw`: Input is read as parameter values with no transformation or parsing. The parameter name should be set with the `--input-param-name` option.
| -| `--input-binary-strings` | The input binary string encoding format. Defines how binary strings in the input should be interpreted.
Available options:
  • `unicode`: Every byte in binary strings that is not a printable ASCII symbol (codes 32-126) should be encoded as UTF-8.
  • `base64`: Binary strings should be fully encoded with base64.
| - -If values are specified for all non-optional (i.e., NOT NULL) parameters [in the `DECLARE` clause](../../yql/reference/syntax/declare.md), the query will be executed on the server. If a value is absent for even one such parameter, the command fails with the error message "Missing value for parameter". - -### More specific options for input parameters {#specific-param-options} - -The following options are not described in the `--help` output. To see their descriptions, use the `-hh` option instead. - -| Name | Description | -| --- | --- | -| `--input-framing` | The input framing format. Defines how parameter sets are delimited in the input.
Available options:
  • `no-framing` (default): Data from the input is taken as a single set of parameters.
  • `newline-delimited`: A newline character delimits parameter sets in the input and triggers processing according to the `--input-batch` option.
| -| `--input-param-name` | The parameter name in the input stream, required when the input format contains only values (that is, when `--input-format raw` is used). | -| `--input-columns` | A string with column names that replaces the CSV/TSV header. Relevant only when passing parameters in CSV/TSV format. It is assumed that the file does not contain a header. | -| `--input-skip-rows` | The number of CSV/TSV header rows to skip in the input data (excluding the row of column names if the `--header` option is used). Relevant only when passing parameters in CSV/TSV format. | -| `--input-batch` | The batch mode applied to parameter sets from `stdin` or `--input-file`.
Available options:
  • `iterative` (default): Executes the query for each parameter set (exactly one execution when `no-framing` is specified for `--input-framing`).
  • `full`: A simplified batch mode where the query runs only once and all the parameter sets received from the input (`stdin` or `--input-file`) are wrapped into a `List<...>`.
  • `adaptive`: Executes the query with a JSON list of parameter sets when either the number of sets reaches `--input-batch-max-rows` or the waiting time reaches `--input-batch-max-delay`.
| -| `--input-batch-max-rows` | The maximum size of the list for the input adaptive batching mode (default: 1000). | -| `--input-batch-max-delay` | The maximum delay before submitting a received parameter set for processing in the `adaptive` batch mode. The value is specified as a number with a time unit: `s` (seconds), `ms` (milliseconds), `m` (minutes), etc. Default value: `1s` (1 second).

The {{ ydb-short-name }} CLI starts a timer when it receives the first set of parameters for the batch from the input and sends the accumulated batch for execution once the timer expires. This parameter enables efficient batching when the arrival rate of new parameter sets is unpredictable. | - -### Examples {#examples-one-request} - -{% include [ydb-cli-profile](../../_includes/ydb-cli-profile.md) %} - -#### Passing the value of a single parameter {#example-simple} - -From the command line using `--param` option: - -```bash -{{ ydb-cli }} -p quickstart sql -s 'DECLARE $a AS Int64; SELECT $a' --param '$a=10' -``` - -Using a file in JSON format (which is used by default): - -```bash -echo '{"a":10}' > p1.json -{{ ydb-cli }} -p quickstart sql -s 'DECLARE $a AS Int64; SELECT $a' --input-file p1.json -``` - -Via `stdin` passing a JSON string as a set of one parameter: - -```bash -echo '{"a":10}' | {{ ydb-cli }} -p quickstart sql -s 'DECLARE $a AS Int64; SELECT $a' -``` - -Via `stdin` passing only a parameter value and setting a parameter name via the `--input-param-name` option: - -```bash -echo '10' | {{ ydb-cli }} -p quickstart sql -s 'DECLARE $a AS Int64; SELECT $a' --input-param-name a -``` - -#### Passing the values of parameters of different types from multiple sources {#example-multisource} - -```bash -# Create a JSON file with fields 'a', 'b', and 'x', where 'x' will be ignored in the query -echo '{ "a":10, "b":"Some text", "x":"Ignore me" }' > p1.json - -# Run the query using ydb-cli, passing in 'a' and 'b' from the input file, and 'c' as a direct parameter -{{ ydb-cli }} -p quickstart sql \ - -s 'DECLARE $a AS Int64; - DECLARE $b AS Utf8; - DECLARE $c AS Int64; - - SELECT $a, $b, $c' \ - --input-file p1.json \ - --param '$c=30' -``` - -Command output: - -```text -┌─────────┬─────────────┬─────────┐ -│ column0 │ column1 │ column2 │ -├─────────┼─────────────┼─────────┤ -│ 10 │ "Some text" │ 30 │ -└─────────┴─────────────┴─────────┘ -``` - -#### Passing Base64-encoded binary strings {#example-base64} - -```bash -{{ ydb-cli }} -p quickstart sql \ - -s 'DECLARE $a AS String; - SELECT $a' \ - --input-format json \ - --input-binary-strings base64 \ - --param '$a="SGVsbG8sIHdvcmxkCg=="' -``` - -Command output: - -```text -┌──────────────────┐ -| column0 | -├──────────────────┤ -| "Hello, world\n" | -└──────────────────┘ -``` - -#### Passing raw binary content directly {#example-raw} - -```bash -curl -Ls http://ydb.tech/docs/en | {{ ydb-cli }} -p quickstart sql \ - -s 'DECLARE $a AS String; - SELECT LEN($a)' \ - --input-format raw \ - --input-param-name a -``` - -Command output (the exact number of bytes may vary): - -```text -┌─────────┐ -| column0 | -├─────────┤ -| 66426 | -└─────────┘ -``` - -#### Passing CSV data {#example-csv} - -```bash -echo '10,Some text' | {{ ydb-cli }} -p quickstart sql \ - -s 'DECLARE $a AS Int32; - DECLARE $b AS String; - SELECT $a, $b' \ - --input-format csv \ - --input-columns 'a,b' -``` - -Command output: - -```text -┌─────────┬─────────────┐ -| column0 | column1 | -├─────────┼─────────────┤ -| 10 | "Some text" | -└─────────┴─────────────┘ -``` - -## Iterative streaming processing {#streaming-iterate} - -{{ ydb-short-name }} CLI supports executing a query multiple times with different sets of parameter values provided via `stdin` **or** an input file (but not both). In this case, the database connection is established once, and the query execution plan is cached. This approach significantly improves performance compared to making separate CLI calls. - -To use this feature, stream different sets of values for the same parameters to the command input (`stdin` or `--input-file`) one after another, specifying a rule for the {{ ydb-short-name }} CLI to separate the sets. - -The query is executed as many times as there are parameter value sets received from the input. Each set is combined with the parameter values defined using the `--param` options. The command completes once the input stream is closed. Each query is executed within a dedicated transaction. - -A rule for separating parameter sets (framing) complements the `--input-format` option: - -| Name | Description | -| --- | --- | -| `--input-framing` | Input framing format. Defines how parameter sets are delimited on the input.
Available options:
  • `no-framing` (default): Data from the input is taken as a single set of parameters.
  • `newline-delimited`: A newline character delimits parameter sets in the input and triggers processing according to the `--input-batch` option.
| - -{% note warning %} - -When using a newline character as a separator between parameter sets, ensure that newline characters are not used inside the parameter sets. Quoting a text value does not allow newlines within the text. Multiline JSON documents are also not allowed. - -{% endnote %} - -### Example {#example-streaming-iterate} - -#### Streaming processing of multiple parameter sets {#example-iterate} - -{% list tabs %} - -- JSON - - Suppose you need to run your query three times with the following sets of values for the `a` and `b` parameters: - - 1. `a` = 10, `b` = 20 - 2. `a` = 15, `b` = 25 - 3. `a` = 35, `b` = 48 - - Let's create a file that contains lines with JSON representations of these sets: - - ```bash - echo -e '{"a":10,"b":20}\n{"a":15,"b":25}\n{"a":35,"b":48}' | tee par1.txt - ``` - - Command output: - - ```text - {"a":10,"b":20} - {"a":15,"b":25} - {"a":35,"b":48} - ``` - - Let's execute the query by passing the content of this file to `stdin`, formatting the output as JSON: - - ```bash - cat par1.txt | \ - {{ ydb-cli }} -p quickstart sql \ - -s 'DECLARE $a AS Int64; - DECLARE $b AS Int64; - SELECT $a + $b' \ - --input-framing newline-delimited \ - --format json-unicode - ``` - - Command output: - - ```text - {"column0":30} - {"column0":40} - {"column0":83} - ``` - - Or just by passing the input file name to the `--input-file` option: - - ```bash - {{ ydb-cli }} -p quickstart sql \ - -s 'DECLARE $a AS Int64; - DECLARE $b AS Int64; - SELECT $a + $b' \ - --input-file par1.txt \ - --input-framing newline-delimited \ - --format json-unicode - ``` - - Command output: - - ```text - {"column0":30} - {"column0":40} - {"column0":83} - ``` - - This output can be passed as input to the next query command if it has a `column0` parameter. - -- CSV - - Suppose you need to run your query three times with the following sets of values for the `a` and `b` parameters: - - 1. `a` = 10, `b` = 20 - 2. `a` = 15, `b` = 25 - 3. `a` = 35, `b` = 48 - - Let's create a file that contains lines with CSV representations of these sets: - - ```bash - echo -e 'a,b\n10,20\n15,25\n35,48' | tee par1.txt - ``` - - Command output: - - ```text - a,b - 10,20 - 15,25 - 35,48 - ``` - - Let's execute the query by passing the content of this file to `stdin`, formatting the output as CSV: - - ```bash - cat par1.txt | \ - {{ ydb-cli }} -p quickstart sql \ - -s 'DECLARE $a AS Int64; - DECLARE $b AS Int64; - SELECT $a + $b' \ - --input-format csv \ - --input-framing newline-delimited \ - --format csv - ``` - - Command output: - - ```text - 30 - 40 - 83 - ``` - - Or just by passing the input file name to the `--input-file` option: - - ```bash - {{ ydb-cli }} -p quickstart sql \ - -s 'DECLARE $a AS Int64; - DECLARE $b AS Int64; - SELECT $a + $b' \ - --input-file par1.txt \ - --input-format csv \ - --input-framing newline-delimited \ - --format csv - ``` - - Command output: - - ```text - 30 - 40 - 83 - ``` - - This output can be passed as input to another command running a different parameterized query. - -- TSV - - Suppose you need to run your query three times, with the following sets of values for the `a` and `b` parameters: - - 1. `a` = 10, `b` = 20 - 2. `a` = 15, `b` = 25 - 3. `a` = 35, `b` = 48 - - Let's create a file that includes lines with TSV representations of these sets: - - ```bash - echo -e 'a\tb\n10\t20\n15\t25\n35\t48' | tee par1.txt - ``` - - Command output: - - ```text - a b - 10 20 - 15 25 - 35 48 - ``` - - Let's execute the query by passing the content of this file to `stdin`, formatting the output as TSV: - - ```bash - cat par1.txt | \ - {{ ydb-cli }} -p quickstart sql \ - -s 'DECLARE $a AS Int64; - DECLARE $b AS Int64; - SELECT $a + $b' \ - --input-format tsv \ - --input-framing newline-delimited \ - --format tsv - ``` - - Command output: - - ```text - 30 - 40 - 83 - ``` - - Or just by passing the input file name to the `--input-file` option: - - ```bash - {{ ydb-cli }} -p quickstart sql \ - -s 'DECLARE $a AS Int64; - DECLARE $b AS Int64; - SELECT $a + $b' \ - --input-file par1.txt \ - --input-format tsv \ - --input-framing newline-delimited \ - --format tsv - ``` - - Command output: - - ```text - 30 - 40 - 83 - ``` - - This output can be passed as input to the next query command. - -{% endlist %} - -#### Streaming processing with joining parameter values from different sources {#example-iterate-union} - -For example, you need to run your query three times with the following sets of values for the `a` and `b` parameters: - -1. `a` = 10, `b` = 100 -2. `a` = 15, `b` = 100 -3. `a` = 35, `b` = 100 - -```bash -echo -e '10\n15\n35' | \ -{{ ydb-cli }} -p quickstart sql \ - -s 'DECLARE $a AS Int64; - DECLARE $b AS Int64; - SELECT $a + $b AS sum1' \ - --param '$b=100' \ - --input-framing newline-delimited \ - --input-param-name a \ - --format json-unicode -``` - -Command output: - -```text -{"sum1":110} -{"sum1":115} -{"sum1":135} -``` - -## Batched streaming processing {#streaming-batch} - -The {{ ydb-short-name }} CLI supports automatic conversion of multiple consecutive parameter sets to a `List<...>`, enabling you to process them in a single request and transaction. As a result, you can achieve a substantial performance gain compared to one-by-one query processing. - -Two batch modes are supported: - -- Full -- Adaptive - -### Full batch mode {#batch-full} - -The `full` mode is a simplified batch mode where the query runs only once, and all the parameter sets received from the input (`stdin` or `--input-file`) are wrapped into a `List<...>`. If the request is too large, you will receive an error. - -Use this batch mode when you want to ensure transaction atomicity by applying all the parameters within a single transaction. - -### Adaptive batch mode {#batch-adaptive} - -In the `adaptive` mode, the input stream is split into multiple transactions, with the batch size automatically determined for each of them. - -In this mode, you can process a broad range of dynamic workloads with unpredictable or infinite amounts of data, as well as workloads with an unpredictable or significantly varying rate of new sets appearing in the input. For example, this scenario is common when sending the output of another command to `stdin` using the `|` operator. - -The adaptive mode solves two key issues of dynamic stream processing: - -1. Limiting the maximum batch size. -2. Limiting the maximum data processing delay. - -### Syntax {#batch-syntax} - -To use the batching capabilities, define the `List<...>` or `List>` parameter in the query's `DECLARE` clause, and use the following options: - -| Name | Description | -| --- | --- | -| `--input-batch` | The batch mode applied to parameter sets on `stdin` or `--input-file`.
Available options:
  • `iterative` (default): Executes the query for each parameter set (exactly one execution when `no-framing` is specified for `--input-framing`).
  • `full`: A simplified batch mode where the query runs only once and all the parameter sets received from the input (`stdin` or `--input-file`) are wrapped into a `List<...>`.
  • `adaptive`: Executes the query with a JSON list of parameter sets whenever the number of sets reaches `--input-batch-max-rows` or the waiting time reaches `--input-batch-max-delay`.
| - -In the adaptive batch mode, you can use the following additional parameters: - -| Name | Description | -| --- | --- | -| `--input-batch-max-rows` | The maximum number of parameter sets per batch in the `adaptive` batch mode. The next batch will be sent with the query if the number of parameter sets reaches the specified limit. When set to `0`, there is no limit.

Default value: `1000`.

Parameter values are sent to each query execution without streaming, so the total size per gRPC request that includes the parameter values has an upper limit of about 5 MB. | -| `--input-batch-max-delay` | The maximum delay before submitting a received parameter set for processing in the `adaptive` batch mode. The value is specified as a number with a time unit: `s` (seconds), `ms` (milliseconds), `m` (minutes), etc. Default value: `1s` (1 second).

The {{ ydb-short-name }} CLI starts a timer when it receives the first set of parameters for the batch from the input and sends the accumulated batch for execution once the timer expires. This parameter enables efficient batching when the arrival rate of new parameter sets is unpredictable. | - -### Examples: Full batch processing {#example-batch-full} - -```bash -echo -e '{"a":10,"b":20}\n{"a":15,"b":25}\n{"a":35,"b":48}' | \ -{{ ydb-cli }} -p quickstart sql \ - -s 'DECLARE $x AS List>; - SELECT ListLength($x), $x' \ - --input-framing newline-delimited \ - --input-param-name x \ - --input-batch full -``` - -Command output: - -```text -┌─────────┬───────────────────────────────────────────────────┐ -| column0 | column1 | -├─────────┼───────────────────────────────────────────────────┤ -| 3 | [{"a":10,"b":20},{"a":15,"b":25},{"a":35,"b":48}] | -└─────────┴───────────────────────────────────────────────────┘ -``` - -### Examples: Adaptive batch processing {#example-batch-adaptive} - -#### Limiting the maximum data processing delay {#example-adaptive-delay} - -This example demonstrates adaptive batching triggered by a processing delay. In the first line of the command below, we generate 1,000 rows with a delay of 0.2 seconds on `stdout` and pipe them to `stdin` for the `ydb sql` query execution command. The query execution command displays the parameter batches in each subsequent query call. - -```bash -for i in $(seq 1 1000); do echo "Line$i"; sleep 0.2; done | \ -{{ ydb-cli }} -p quickstart sql \ - -s 'DECLARE $x AS List; - SELECT ListLength($x), $x' \ - --input-framing newline-delimited \ - --input-format raw \ - --input-param-name x \ - --input-batch adaptive -``` - -Command output (the actual values may differ): - -```text -┌─────────┬────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -| column0 | column1 | -├─────────┼────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ -| 14 | ["Line1","Line2","Line3","Line4","Line5","Line6","Line7","Line8","Line9","Line10","Line11","Line12","Line13","Line14"] | -└─────────┴────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -┌─────────┬─────────────────────────────────────────────────────────┐ -| column0 | column1 | -├─────────┼─────────────────────────────────────────────────────────┤ -| 6 | ["Line15","Line16","Line17","Line18","Line19","Line20"] | -└─────────┴─────────────────────────────────────────────────────────┘ -┌─────────┬─────────────────────────────────────────────────────────┐ -| column0 | column1 | -├─────────┼─────────────────────────────────────────────────────────┤ -| 6 | ["Line21","Line22","Line23","Line24","Line25","Line26"] | -└─────────┴─────────────────────────────────────────────────────────┘ -^C -``` - -The first batch includes all the rows accumulated at the input while the database connection was being established, which is why it is larger than the subsequent ones. - -You can terminate the command by pressing Ctrl+C or wait 200 seconds until the input generation is finished. - -#### Limit on the number of records {#example-adaptive-limit} - -This example demonstrates adaptive batching triggered by the number of parameter sets. In the first line of the command below, we generate 200 rows. The command displays parameter batches in each subsequent query call, applying the specified limit `--input-batch-max-rows` of 20 (the default limit is 1,000). - -This example also demonstrates the option to join parameters from different sources and generate JSON as output. - -```bash -for i in $(seq 1 200); do echo "Line$i"; done | \ -{{ ydb-cli }} -p quickstart sql \ - -s 'DECLARE $x AS List; - DECLARE $p2 AS Int64; - SELECT ListLength($x) AS count, $p2 AS p2, $x AS items' \ - --input-framing newline-delimited \ - --input-format raw \ - --input-param-name x \ - --input-batch adaptive \ - --input-batch-max-rows 20 \ - --param '$p2=10' \ - --format json-unicode -``` - -Command output: - -```text -{"count":20,"p2":10,"items":["Line1","Line2","Line3","Line4","Line5","Line6","Line7","Line8","Line9","Line10","Line11","Line12","Line13","Line14","Line15","Line16","Line17","Line18","Line19","Line20"]} -{"count":20,"p2":10,"items":["Line21","Line22","Line23","Line24","Line25","Line26","Line27","Line28","Line29","Line30","Line31","Line32","Line33","Line34","Line35","Line36","Line37","Line38","Line39","Line40"]} -... -{"count":20,"p2":10,"items":["Line161","Line162","Line163","Line164","Line165","Line166","Line167","Line168","Line169","Line170","Line171","Line172","Line173","Line174","Line175","Line176","Line177","Line178","Line179","Line180"]} -{"count":20,"p2":10,"items":["Line181","Line182","Line183","Line184","Line185","Line186","Line187","Line188","Line189","Line190","Line191","Line192","Line193","Line194","Line195","Line196","Line197","Line198","Line199","Line200"]} -``` - -#### Deleting multiple records from a {{ ydb-short-name }} table based on primary keys {#example-adaptive-delete-pk} - -If you attempt to delete a large number of rows from a substantial table using a simple `DELETE FROM large_table WHERE id > 10;` statement, you may encounter an error due to exceeding the transaction record limit. This example shows how to delete an unlimited number of records from {{ ydb-short-name }} tables without breaching this limitation. - -Let's create a test table: - -```bash -{{ ydb-cli }} -p quickstart sql -s 'CREATE TABLE test_delete_1(id UInt64 NOT NULL, PRIMARY KEY (id))' -``` - -Add 100,000 records to it: - -```bash -for i in $(seq 1 100000); do echo "$i"; done | \ -{{ ydb-cli }} -p quickstart import file csv -p test_delete_1 -``` - -Delete all records with `id` greater than 10: - -```bash -{{ ydb-cli }} -p quickstart sql \ - -s 'SELECT t.id FROM test_delete_1 AS t WHERE t.id > 10' \ - --format json-unicode | \ -{{ ydb-cli }} -p quickstart sql \ - -s 'DECLARE $lines AS List>; - DELETE FROM test_delete_1 WHERE id IN (SELECT tl.id FROM AS_TABLE($lines) AS tl)' \ - --input-framing newline-delimited \ - --input-param-name lines \ - --input-batch adaptive \ - --input-batch-max-rows 10000 -``` - -#### Processing messages read from a topic {#example-adaptive-pipeline-from-topic} - -Examples of processing messages read from a topic are provided in [{#T}](topic-pipeline.md#example-read-to-yql-param). - -## See also {#see-also} - -* [Parameterized queries in {{ ydb-short-name }} SDK](../ydb-sdk/parameterized_queries.md) diff --git a/ydb/docs/ru/core/reference/ydb-cli/parameterized-query-execution.md b/ydb/docs/ru/core/reference/ydb-cli/parameterized-query-execution.md deleted file mode 100644 index 7d942845b6a4..000000000000 --- a/ydb/docs/ru/core/reference/ydb-cli/parameterized-query-execution.md +++ /dev/null @@ -1,591 +0,0 @@ -# Выполнение параметризованных запросов - -## Обзор - -{{ ydb-short-name }} CLI поддерживает исполнение [параметризованных запросов](https://en.wikipedia.org/wiki/Prepared_statement). Для работы с параметрами в тексте запроса должны присутствовать их определения [командой YQL `DECLARE`](../../yql/reference/syntax/declare.md). - -Основной инструмент для выполнения параметризованных запросов в {{ ydb-short-name }} CLI — это команда [{{ ydb-cli }} sql](sql.md). - -## Зачем использовать параметризованные запросы? - -Использование параметризованных запросов предоставляет несколько важных преимуществ: - -* **Улучшенная производительность:** Параметризованные запросы значительно повышают производительность при выполнении множества схожих запросов, которые различаются только входными параметрами. Это достигается с помощью [подготовленных запросов](https://en.wikipedia.org/wiki/Prepared_statement). Запрос компилируется один раз и затем кешируется на сервере. Последующие запросы с тем же текстом минуют фазу компиляции и сразу начинают выполняться. - -* **Защита от SQL-инъекций:** Другим важным преимуществом использования параметризованных запросов является защита от [SQL-инъекций](https://en.wikipedia.org/wiki/SQL_injection). Эта функция безопасности гарантирует правильную обработку входных данных, что снижает риск выполнения вредоносного кода. - -## Единичное исполнение запроса {#one-request} - -Эта команда поддерживает передачу параметров через опции командной строки, файл, а также через `stdin`. При передаче параметров через `stdin` или файл поддерживается многократное поточное исполнение запроса с разными значениями параметров и возможностью пакетирования. Для этого в команде [{{ ydb-cli }} sql](sql.md) предназначены следующие параметры: - -| Имя | Описание | -| ---|--- | -| `-p, --param` | Значение одного параметра запроса в формате `$name=value` или `name=value`, где `name` — имя параметра, а `value` — его значение (корректный [JSON value](https://www.json.org/json-ru.html)). | -| `--input-file` | Имя файла в формате [JSON](https://ru.wikipedia.org/wiki/JSON) в кодировке [UTF-8](https://ru.wikipedia.org/wiki/UTF-8), в котором заданы значения параметров, сопоставляемые с параметрами запроса по именам ключей. Может быть использован максимум один файл с параметрами. | -| `--input-format` | Формат представления значений параметров. Действует на все способы их передачи (через параметр команды, файл или `stdin`).
Возможные значения:
  • `json` (по умолчанию): Формат [JSON](https://ru.wikipedia.org/wiki/JSON).
  • `csv` — формат [CSV](https://ru.wikipedia.org/wiki/CSV). По умолчанию имена параметров должны находиться в header'е CSV файла. При единичном исполнении запроса допустима только одна строка в файле, не считая header'a.
  • `tsv` — формат [TSV](https://ru.wikipedia.org/wiki/TSV).
  • `raw`: Входной поток из `stdin` или `--input-file` содержит только значение параметра в виде бинарных данных. Имя параметра должно быть указано опцией `--input-param-name`.
| -| `--input-binary-strings` | Формат кодировния значения параметров с типом «бинарная строка» (`DECLARE $par AS String`). Говорит о том, как должны интерпретироваться бинарные строки из входного потока.
Возможные значения:
  • `unicode`: Каждый байт в бинарной строке, не являющийся печатаемым ASCII-символом (codes 32-126), должен быть закодирован в кодировке [UTF-8](https://ru.wikipedia.org/wiki/UTF-8).
  • `base64`: Бинарные строки представлены в кодировке [Base64](https://ru.wikipedia.org/wiki/Base64). Такая возможность позволяет передавать бинарные данные, декодирование которых из Base64 выполнит {{ ydb-short-name }} CLI.
| - -Если значения указаны для всех параметров, которые не допускают `NULL` (то есть с типом NOT NULL), [в составе оператора `DECLARE`](../../yql/reference/syntax/declare.md), запрос будет выполнен на сервере. Если отсутствует значение хотя бы для одного такого параметра, выполнение команды завершится с ошибкой и сообщением "Не задано значение для параметра". - -### Более специфичные опции для использования входных параметров {#specific-param-options} - -Следующие опции не представлены в выводе `--help`. Их описание можно увидеть только в выводе `-hh`. - -| Имя | Описание | -| ---|--- | -| `--input-framing` | Задает фрейминг для входного потока (`stdin` или `--input-file`). Определяет как входной поток будет разделяться на отдельные наборы параметров.
Возможные значения:
  • `no-framing` (по умолчанию): От входного потока ожидается один набор параметров, запрос исполняется однократно.
  • `newline-delimited`: Символ перевода строки отмечает во входном потоке окончание одного набора параметров, отделяя его от следующего. Набор параметров считается собранным каждый раз при получении во входном потоке символа перевода строки.
| -| `--input-param-name` | Имя параметра, значение которого передано во входной поток. Указывается без символа `$`. Обязательно при использовании формата `raw` в `--input-format`.

При использовании с JSON-форматом входной поток интерпретируется не как JSON-документ, а как JSON value, с передачей значения в параметр с указанным именем. | -| `--input-columns` | Строка с именами колонок, заменяющими header CSV/TSV документа, читаемого из входного потока. При указании опции считается, что header отсутствует. Опция допустима только с форматами CSV и TSV.| -| `--input-skip-rows` | Число строк с начала данных, читаемых со stdin'a, которые нужно пропустить, не включая строку header'a, если она имеется. Опция допустима только с форматами stdin'a CSV и TSV. | -| `--input-batch` | Режим пакетирования значений наборов параметров, получаемых из входного потока (`stdin` или `--input-file`).
Возможные значения:
  • `iterative` (по умолчанию): Пакетирование [выключено](#streaming-iterate). Запрос выполняется для каждого набора параметров (ровно один раз, если в опции `--input-framing` используется `no-framing`)
  • `full`: Полный пакет. Запрос выполнится один раз после завершения чтения входного потока, все полученные наборы параметров заворачиваются в `List<...>`, имя параметра задается опцией `--input-param-name`
  • `adaptive`: Адаптивное пакетирование. Запрос выполняется каждый раз, когда срабатывает ограничение на количество наборов параметров в одном запросе (`--input-batch-max-rows`) или на задержку обработки (`--input-batch-max-delay`). Все полученные к этому моменту наборы параметров заворачиваются в `List<...>`, имя параметра задается опцией `--input-param-name`.
| -| `--input-batch-max-rows` | Максимальное количество наборов параметров в пакете для адаптивного режима пакетирования. Следующий пакет будет отправлен на исполнение вместе с запросом, если количество наборов данных в нем достигло указанного значения. Установка в `0` снимает ограничение.

Значение по умолчанию — `1000`.

Параметры передаются в запрос без стриминга и общий объем одного GRPC-запроса, в который включаются значения параметров, имеет верхнюю границу около 5 МБ. | -| `--input-batch-max-delay` | Максимальная задержка отправки на обработку полученного набора параметров для адаптивного режима пакетирования. Задается в виде числа с размерностью времени - `s` (секунды), `ms` (миллисекунды), `m` (минуты) и т.д. Значение по умолчанию — `1s` (1 секунда).

{{ ydb-short-name }} CLI будет отсчитывать время с момента получения первого набора параметров для пакета и отправит накопившийся пакет на исполнение, как только время превысит указанное значение. Параметр позволяет получить эффективное пакетирование в случае непредсказуемого темпа появления новых наборов параметров на `stdin`. | - -### Примеры {#examples-one-request} - -{% include [ydb-cli-profile](../../_includes/ydb-cli-profile.md) %} - -#### Передача значения одного параметра {#example-simple} - -В командной строке, через опцию `--param`: - -```bash -{{ ydb-cli }} -p quickstart sql -s 'DECLARE $a AS Int64; SELECT $a' --param '$a=10' -``` - -Через файл в формате JSON (который используется по умолчанию): - -```bash -echo '{"a":10}' > p1.json -{{ ydb-cli }} -p quickstart sql -s 'DECLARE $a AS Int64; SELECT $a' --input-file p1.json -``` - -Через `stdin`, передавая JSON-строку как набор из одного параметра: - -```bash -echo '{"a":10}' | {{ ydb-cli }} -p quickstart sql -s 'DECLARE $a AS Int64; SELECT $a' -``` - -Через `stdin`, передавая только значение параметра и задавая имя параметра через опцию `--input-param-name`: - -```bash -echo '10' | {{ ydb-cli }} -p quickstart sql -s 'DECLARE $a AS Int64; SELECT $a' --input-param-name a -``` - -#### Передача значений параметров разных типов из нескольких источников {#example-multisource} - -```bash -# Create a JSON file with fields 'a', 'b', and 'x', where 'x' will be ignored in the query -echo '{ "a":10, "b":"Some text", "x":"Ignore me" }' > p1.json - -# Run the query using ydb-cli, passing in 'a' and 'b' from the input file, and 'c' as a direct parameter -{{ ydb-cli }} -p quickstart sql \ - -s 'DECLARE $a AS Int64; - DECLARE $b AS Utf8; - DECLARE $c AS Int64; - - SELECT $a, $b, $c' \ - --input-file p1.json \ - --param '$c=30' -``` - -Вывод команды: - -```text -┌─────────┬─────────────┬─────────┐ -│ column0 │ column1 │ column2 │ -├─────────┼─────────────┼─────────┤ -│ 10 │ "Some text" │ 30 │ -└─────────┴─────────────┴─────────┘ -``` - -#### Передача бинарных строк в кодировке Base64 {#example-base64} - -```bash -{{ ydb-cli }} -p quickstart sql \ - -s 'DECLARE $a AS String; - SELECT $a' \ - --input-format json \ - --input-binary-strings base64 \ - --param '$a="SGVsbG8sIHdvcmxkCg=="' -``` - -Вывод команды: - -```text -┌──────────────────┐ -| column0 | -├──────────────────┤ -| "Hello, world\n" | -└──────────────────┘ -``` - -#### Прямая передача бинарного контента {#example-raw} - -```bash -curl -Ls http://ydb.tech/docs/en | {{ ydb-cli }} -p quickstart sql \ - -s 'DECLARE $a AS String; - SELECT LEN($a)' \ - --input-format raw \ - --input-param-name a -``` - -Вывод команды (точное количество байт может отличаться): - -```text -┌─────────┐ -| column0 | -├─────────┤ -| 66426 | -└─────────┘ -``` - -#### Передача файла в формате CSV {#example-csv} - -```bash -echo '10,Some text' | {{ ydb-cli }} -p quickstart sql \ - -s 'DECLARE $a AS Int32; - DECLARE $b AS String; - SELECT $a, $b' \ - --input-format csv \ - --input-columns 'a,b' -``` - -Вывод команды: - -```text -┌─────────┬─────────────┐ -| column0 | column1 | -├─────────┼─────────────┤ -| 10 | "Some text" | -└─────────┴─────────────┘ -``` - -## Итеративная потоковая обработка {#streaming-iterate} - -{{ ydb-short-name }} CLI поддерживает возможность многократного исполнения запроса с разными наборами значений параметров, при их передаче через `stdin` **или** входной файл (не одновременно). При этом соединение с базой данных устанавливается однократно, а план исполнения запроса кешируется, что существенно повышает производительность такого подхода по сравнению с отдельными вызовами CLI. - -Для того чтобы воспользоваться этой возможностью, необходимо на вход команды друг за другом передавать разные наборы значений одних и тех параметров, сообщив {{ ydb-short-name }} CLI правило, по которому будет возможно отделить эти наборы друг от друга. - -Запрос выполняется столько раз, сколько наборов значений параметров было получено. Каждый полученный через входной поток (`stdin` или `--input-file`) набор объединяется со значениями параметров, определенными через опции `--param`. Исполнение команды будет завершено после завершения входного потока. Каждый запрос исполняется в своей транзакции. - -Правило отделения наборов параметров друг от друга (фрейминг) дополняет описание формата представления параметров на входном потоке, задаваемое параметром `--input--framing`: - -| Имя | Описание | -| ---|--- | -| `--input-framing` | Задает фрейминг для входного потока (файл или `stdin`).
Возможные значения:
  • `no-framing` (по умолчанию) — на входе ожидается один набор параметров, запрос исполняется однократно после завершения чтения потока.
  • `newline-delimited` — символ перевода строки отмечает на входе окончание одного набора параметров, отделяя его от следующего. Запрос исполняется каждый раз при получении символа перевода строки.
| - -{% note warning %} - -При использовании символа перевода строки в качестве разделителя наборов параметров необходимо гарантировать его отсутствие внутри наборов параметров. Заключение текста в кавычки не делает допустимым перевод строки внутри такого текста. Многострочные JSON-документы не допускаются. - -{% endnote %} - -### Пример {#example-streaming-iterate} - -#### Потоковая обработка нескольких наборов параметров {#example-iterate} - -{% list tabs %} - -- JSON - - Допустим, нам необходимо выполнить запрос трижды, со следующими наборами значений параметров `a` и `b`: - - 1. `a` = 10, `b` = 20 - 2. `a` = 15, `b` = 25 - 3. `a` = 35, `b` = 48 - - Создадим файл, который будет содержать строки с JSON-представлением этих наборов: - - ```bash - echo -e '{"a":10,"b":20}\n{"a":15,"b":25}\n{"a":35,"b":48}' | tee par1.txt - ``` - - Вывод команды: - - ```text - {"a":10,"b":20} - {"a":15,"b":25} - {"a":35,"b":48} - ``` - - Исполним запрос, передав на `stdin` содержимое данного файла, с форматированием вывода в JSON: - - ```bash - cat par1.txt | \ - {{ ydb-cli }} -p quickstart sql \ - -s 'DECLARE $a AS Int64; - DECLARE $b AS Int64; - SELECT $a+$b' \ - --input-framing newline-delimited \ - --format json-unicode - ``` - - Вывод команды: - - ```text - {"column0":30} - {"column0":40} - {"column0":83} - ``` - - Или просто передав имя файла в опцию `--input-file`: - - ```bash - {{ ydb-cli }} -p quickstart sql \ - -s 'DECLARE $a AS Int64; - DECLARE $b AS Int64; - SELECT $a + $b' \ - --input-file par1.txt \ - --input-framing newline-delimited \ - --format json-unicode - ``` - - Вывод команды: - - ```text - {"column0":30} - {"column0":40} - {"column0":83} - ``` - - Полученный в таком формате результат можно использовать для передачи на вход команде исполнения следующего запроса. - -- CSV - - Допустим, нам необходимо выполнить запрос трижды, со следующими наборами значений параметров `a` и `b`: - - 1. `a` = 10, `b` = 20 - 2. `a` = 15, `b` = 25 - 3. `a` = 35, `b` = 48 - - Создадим файл c наборами значений параметров в формате CSV: - - ```bash - echo -e 'a,b\n10,20\n15,25\n35,48' | tee par1.txt - ``` - - Вывод команды: - - ```text - a,b - 10,20 - 15,25 - 35,48 - ``` - - Исполним запрос, передав на `stdin` содержимое данного файла, с форматированием вывода в CSV: - - ```bash - cat par1.txt | \ - {{ ydb-cli }} -p quickstart sql \ - -s 'DECLARE $a AS Int64; - DECLARE $b AS Int64; - SELECT $a + $b' \ - --input-format csv \ - --input-framing newline-delimited \ - --format csv - ``` - - Вывод команды: - - ```text - 30 - 40 - 83 - ``` - - Или просто передав имя файла в опцию `--input-file`: - - ```bash - {{ ydb-cli }} -p quickstart sql \ - -s 'DECLARE $a AS Int64; - DECLARE $b AS Int64; - SELECT $a + $b' \ - --input-file par1.txt \ - --input-format csv \ - --input-framing newline-delimited \ - --format csv - ``` - - Вывод команды: - - ```text - 30 - 40 - 83 - ``` - - Полученный в таком формате результат можно использовать для передачи на вход команде исполнения следующего запроса, задав header данным в CSV формате опцией `--input-columns`. - -- TSV - - Допустим, нам необходимо выполнить запрос трижды, со следующими наборами значений параметров `a` и `b`: - - 1. `a` = 10, `b` = row1 - 2. `a` = 15, `b` = row 2 - 3. `a` = 35, `b` = "row"\n3 - - Создадим файл c наборами значений параметров в формате TSV: - - ```bash - echo -e 'a\tb\n10\t20\n15\t25\n35\t48' | tee par1.txt - ``` - - Вывод команды: - - ```text - a b - 10 20 - 15 25 - 35 48 - ``` - - Исполним запрос, передав на `stdin` содержимое данного файла, с форматированием вывода в TSV: - - ```bash - cat par1.txt | \ - {{ ydb-cli }} -p quickstart sql \ - -s 'DECLARE $a AS Int64; - DECLARE $b AS Utf8; - SELECT $a, $b' \ - --input-framing newline-delimited \ - --input-format tsv \ - --format tsv - ``` - - Вывод команды: - - ```text - 30 - 40 - 83 - ``` - - Или просто передав имя файла в опцию `--input-file`: - - ```bash - {{ ydb-cli }} -p quickstart sql \ - -s 'DECLARE $a AS Int64; - DECLARE $b AS Int64; - SELECT $a + $b' \ - --input-file par1.txt \ - --input-format tsv \ - --input-framing newline-delimited \ - --format tsv - ``` - - Вывод команды: - - ```text - 30 - 40 - 83 - ``` - - Полученный в таком формате результат можно использовать для передачи на вход команде исполнения следующего запроса, задав header данным в TSV формате опцией `--input-columns`. - -{% endlist %} - -#### Потоковая обработка с объединением значений параметров из разных источников {#example-iterate-union} - -Допустим, нам необходимо выполнить запрос трижды, со следующими наборами значений параметров `a` и `b`: - -1. `a` = 10, `b` = 100 -2. `a` = 15, `b` = 100 -3. `a` = 35, `b` = 100 - -```bash -echo -e '10\n15\n35' | \ -{{ ydb-cli }} -p quickstart sql \ - -s 'DECLARE $a AS Int64; - DECLARE $b AS Int64; - SELECT $a + $b AS sum1' \ - --param '$b=100' \ - --input-framing newline-delimited \ - --input-param-name a \ - --format json-unicode -``` - -Вывод команды: - -```text -{"sum1":110} -{"sum1":115} -{"sum1":135} -``` - -## Пакетная потоковая обработка {#streaming-batch} - -{{ ydb-short-name }} CLI поддерживает автоматическую конвертацию наборов параметров в `List<...>`, позволяя одним запросом к серверу обработать множество наборов параметров в одной транзакции, что может дополнительно существенно повышать производительность по сравнению с выполнением запросов "по одному". - -Поддерживаются два режима пакетирования: - -- Полный (`full`); -- Адаптивный (`adaptive`). - -### Полный режим пакетирования {#batch-full} - -Полный (`full`) режим является упрощенным вариантом пакетирования, когда запрос выполняется один раз, с заворачиванием в `List<...>` всех полученных с входного потока наборов параметров. Если размер запроса окажется слишком большим, будет выдана ошибка. - -Данный вариант пакетирования необходим в случае, когда необходимо гарантировать атомарность за счет применения всех параметров в одной транзакции. - -### Адаптивный режим пакетирования {#batch-adaptive} - -При работе в адаптивном (`adaptive`) режиме обработка входного потока разбивается на множество транзакций, с автоматическим подбором размера пакета для каждой из них. - -Данный режим позволяет эффективно обрабатывать широкий спектр входной нагрузки, с непредсказуемым или бесконечным количеством данных, а также непредсказуемым или сильно меняющимся темпом их появления на входе. В частности, такой профиль характерен при подаче на `stdin` выхода другой команды через оператор `|`. - -Адаптивный режим решает две основные проблемы обработки динамического потока: - -1. Ограничение максимального размера пакета. -2. Ограничение максимальной задержки обработки данных. - -### Синтаксис {#batch-syntax} - -Для того чтобы воспользоваться возможностью пакетирования, необходимо описать параметр типа `List<...>` или `List>` в секции DECLARE запроса, и выбрать режим следующим параметром: - -| Имя | Описание | -| ---|--- | -| `--input-batch` | Режим пакетирования значений наборов параметров, получаемых из входного потока (`stdin` или `--input-file`).
Возможные значения:
  • `iterative` (по умолчанию): Пакетирование [выключено](#streaming-iterate). Запрос выполняется для каждого набора параметров (ровно один раз, если в опции `--input-framing` используется `no-framing`)
  • `full`: Полный пакет. Запрос выполнится один раз после завершения чтения входного потока, все полученные наборы параметров заворачиваются в `List<...>`, имя параметра задается опцией `--input-param-name`
  • `adaptive`: Адаптивное пакетирование. Запрос выполняется каждый раз, когда срабатывает ограничение на количество наборов параметров в одном запросе (`--input-batch-max-rows`) или на задержку обработки (`--input-batch-max-delay`). Все полученные к этому моменту наборы параметров заворачиваются в `List<...>`, имя параметра задается опцией `--input-param-name`.
| - -В адаптивном режиме пакетирования доступны дополнительные параметры: - -| Имя | Описание | -| ---|--- | -| `--input-batch-max-rows` | Максимальное количество наборов параметров в пакете для адаптивного режима пакетирования. Следующий пакет будет отправлен на исполнение вместе с запросом, если количество наборов данных в нем достигло указанного значения. Установка в `0` снимает ограничение.

Значение по умолчанию — `1000`.

Параметры передаются в запрос без стриминга и общий объем одного GRPC-запроса, в который включаются значения параметров, имеет верхнюю границу около 5 МБ. | -| `--input-batch-max-delay` | Максимальная задержка отправки на обработку полученного набора параметров для адаптивного режима пакетирования. Задается в виде числа с размерностью времени - `s` (секунды), `ms` (миллисекунды), `m` (минуты) и т.д. Значение по умолчанию — `1s` (1 секунда).

{{ ydb-short-name }} CLI будет отсчитывать время с момента получения первого набора параметров для пакета и отправит накопившийся пакет на исполнение, как только время превысит указанное значение. Параметр позволяет получить эффективное пакетирование в случае непредсказуемого темпа появления новых наборов параметров на `stdin`. | - -### Примеры - полная пакетная обработка {#example-batch-full} - -```bash -echo -e '{"a":10,"b":20}\n{"a":15,"b":25}\n{"a":35,"b":48}' | \ -{{ ydb-cli }} -p quickstart sql \ - -s 'DECLARE $x AS List>; - SELECT ListLength($x), $x' \ - --input-framing newline-delimited \ - --input-param-name x \ - --input-batch full -``` - -Вывод команды: - -```text -┌─────────┬───────────────────────────────────────────────────┐ -| column0 | column1 | -├─────────┼───────────────────────────────────────────────────┤ -| 3 | [{"a":10,"b":20},{"a":15,"b":25},{"a":35,"b":48}] | -└─────────┴───────────────────────────────────────────────────┘ -``` - -### Примеры - адаптивная пакетная обработка {#example-batch-adaptive} - -#### Ограничение максимальной задержки обработки {#example-adaptive-delay} - -Для демонстрации работы адаптивного пакетирования со срабатыванием ограничения по задержке обработки в первой строке команды ниже производится генерация 1000 строк с задержкой в 0.2 секунды в `stdout`, которые передаются на `stdin` команде исполнения запроса. Команда исполнения запроса, в свою очередь, отображает пакеты параметров в каждом следующем вызове запроса. - -```bash -for i in $(seq 1 1000); do echo "Line$i"; sleep 0.2; done | \ -{{ ydb-cli }} -p quickstart sql \ - -s 'DECLARE $x AS List; - SELECT ListLength($x), $x' \ - --input-framing newline-delimited \ - --input-format raw \ - --input-param-name x \ - --input-batch adaptive -``` - -Вывод команды (точные значения могут отличаться): - -```text -┌─────────┬────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -| column0 | column1 | -├─────────┼────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ -| 14 | ["Line1","Line2","Line3","Line4","Line5","Line6","Line7","Line8","Line9","Line10","Line11","Line12","Line13","Line14"] | -└─────────┴────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -┌─────────┬─────────────────────────────────────────────────────────┐ -| column0 | column1 | -├─────────┼─────────────────────────────────────────────────────────┤ -| 6 | ["Line15","Line16","Line17","Line18","Line19","Line20"] | -└─────────┴─────────────────────────────────────────────────────────┘ -┌─────────┬─────────────────────────────────────────────────────────┐ -| column0 | column1 | -├─────────┼─────────────────────────────────────────────────────────┤ -| 6 | ["Line21","Line22","Line23","Line24","Line25","Line26"] | -└─────────┴─────────────────────────────────────────────────────────┘ -^C -``` - -В первый пакет попадают все строки, накопившиеся на входе за время открытия соединения с БД, и поэтому он больше чем последующие. - -Выполнение команды можно прервать по Ctrl+C, или дождаться пока пройдут 200 секунд, в течение которых генерируется вход. - -#### Ограничение по количеству записей {#example-adaptive-limit} - -Для демонстрации работы адаптивного пакетирования со срабатыванием триггера по количеству наборов параметров в первой строке команды ниже производится генерация 200 строк. Команда будет отображать пакеты параметров в каждом следующем вызове запроса, учитывая заданное ограничение `--input-batch-max-rows` равное 20 (по умолчанию 1000). - -В данном примере также показана возможность объединения параметров из разных источников, и формирование JSON на выходе. - -```bash -for i in $(seq 1 200); do echo "Line$i"; done | \ -{{ ydb-cli }} -p quickstart sql \ - -s 'DECLARE $x AS List; - DECLARE $p2 AS Int64; - SELECT ListLength($x) AS count, $p2 AS p2, $x AS items' \ - --input-framing newline-delimited \ - --input-format raw \ - --input-param-name x \ - --input-batch adaptive \ - --input-batch-max-rows 20 \ - --param '$p2=10' \ - --format json-unicode -``` - -Вывод команды: - -```text -{"count":20,"p2":10,"items":["Line1","Line2","Line3","Line4","Line5","Line6","Line7","Line8","Line9","Line10","Line11","Line12","Line13","Line14","Line15","Line16","Line17","Line18","Line19","Line20"]} -{"count":20,"p2":10,"items":["Line21","Line22","Line23","Line24","Line25","Line26","Line27","Line28","Line29","Line30","Line31","Line32","Line33","Line34","Line35","Line36","Line37","Line38","Line39","Line40"]} -... -{"count":20,"p2":10,"items":["Line161","Line162","Line163","Line164","Line165","Line166","Line167","Line168","Line169","Line170","Line171","Line172","Line173","Line174","Line175","Line176","Line177","Line178","Line179","Line180"]} -{"count":20,"p2":10,"items":["Line181","Line182","Line183","Line184","Line185","Line186","Line187","Line188","Line189","Line190","Line191","Line192","Line193","Line194","Line195","Line196","Line197","Line198","Line199","Line200"]} -``` - -#### Удаление множества записей из строковой таблицы {{ ydb-short-name }} по первичным ключам {#example-adaptive-delete-pk} - -Если вы попытаетесь удалить большое количество строк из крупной таблицы с помощью простого запроса `DELETE FROM large_table WHERE id > 10;`, вы можете столкнуться с ошибкой из-за превышения ограничения на количество записей в транзакции. Данный пример показывает, как можно удалять неограниченное количество записей из таблиц {{ ydb-short-name }} без нарушения этого ограничения. -Создадим тестовую строковую таблицу: - -```bash -{{ ydb-cli }} -p quickstart sql -s 'CREATE TABLE test_delete_1(id UInt64 NOT NULL, PRIMARY KEY (id))' -``` - -Занесем в неё 100,000 записей: - -```bash -for i in $(seq 1 100000); do echo "$i";done | \ -{{ ydb-cli }} -p quickstart import file csv -p test_delete_1 -``` - -Удалим все записи со значениями `id` больше 10: - -```bash -{{ ydb-cli }} -p quickstart sql \ - -s 'SELECT t.id FROM test_delete_1 AS t WHERE t.id > 10' \ - --format json-unicode | \ -{{ ydb-cli }} -p quickstart sql \ - -s 'DECLARE $lines AS List>; - DELETE FROM test_delete_1 WHERE id IN (SELECT tl.id FROM AS_TABLE($lines) AS tl)' \ - --input-framing newline-delimited \ - --input-param-name lines \ - --input-batch adaptive \ - --input-batch-max-rows 10000 -``` - -#### Обработка сообщений, считываемых из топика {#example-adaptive-pipeline-from-topic} - -Примеры обработки сообщений, считываемых из топика, приведены в статье [{#T}](topic-pipeline.md#example-read-to-yql-param). - -## См. также {#see-also} - -* [Параметризованные запросы в {{ ydb-short-name }} SDK](../ydb-sdk/parameterized_queries.md)