Esta página descreve como criar, alterar e eliminar uma sequência no Spanner através de declarações de linguagem de definição de dados (LDD). Também pode ver como usar uma sequência num valor predefinido para preencher uma coluna de chave principal.
Consulte a referência completa da sintaxe DDL de sequência para (bases de dados com dialeto GoogleSQL e bases de dados com dialeto PostgreSQL).
Crie uma sequência
O exemplo de código seguinte cria uma sequência Seq, usa-a no valor predefinido da chave primária da tabela Customers e insere três novas linhas na tabela Customers.
GoogleSQL
C++
void CreateSequence(
google::cloud::spanner_admin::DatabaseAdminClient admin_client,
google::cloud::spanner::Client client, std::string const& project_id,
std::string const& instance_id, std::string const& database_id) {
google::cloud::spanner::Database database(project_id, instance_id,
database_id);
std::vector<std::string> statements;
statements.emplace_back(R"""(
CREATE SEQUENCE Seq
OPTIONS (sequence_kind = 'bit_reversed_positive')
)""");
statements.emplace_back(R"""(
CREATE TABLE Customers (
CustomerId INT64 DEFAULT (GET_NEXT_SEQUENCE_VALUE(SEQUENCE Seq)),
CustomerName STRING(1024)
) PRIMARY KEY (CustomerId)
)""");
auto metadata =
admin_client.UpdateDatabaseDdl(database.FullName(), std::move(statements))
.get();
if (!metadata) throw std::move(metadata).status();
std::cout << "Created `Seq` sequence and `Customers` table,"
<< " where the key column `CustomerId`"
<< " uses the sequence as a default value,"
<< " new DDL:\n"
<< metadata->DebugString();
auto commit = client.Commit(
[&client](google::cloud::spanner::Transaction txn)
-> google::cloud::StatusOr<google::cloud::spanner::Mutations> {
auto sql = google::cloud::spanner::SqlStatement(R"""(
INSERT INTO Customers (CustomerName)
VALUES ('Alice'),
('David'),
('Marc')
THEN RETURN CustomerId
)""");
using RowType = std::tuple<std::int64_t>;
auto rows = client.ExecuteQuery(std::move(txn), std::move(sql));
// Note: This mutator might be re-run, or its effects discarded, so
// changing non-transactional state (e.g., by producing output) is,
// in general, not something to be imitated.
for (auto& row : google::cloud::spanner::StreamOf<RowType>(rows)) {
if (!row) return std::move(row).status();
std::cout << "Inserted customer record with CustomerId: "
<< std::get<0>(*row) << "\n";
}
std::cout << "Number of customer records inserted is: "
<< rows.RowsModified() << "\n";
return google::cloud::spanner::Mutations{};
});
if (!commit) throw std::move(commit).status();
}C#
using Google.Cloud.Spanner.Admin.Database.V1;
using Google.Cloud.Spanner.Common.V1;
using Google.Cloud.Spanner.Data;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
public class CreateSequenceSample
{
public async Task<List<long>> CreateSequenceAsync(string projectId, string instanceId, string databaseId)
{
DatabaseAdminClient databaseAdminClient = DatabaseAdminClient.Create();
DatabaseName databaseName = DatabaseName.FromProjectInstanceDatabase(projectId, instanceId, databaseId);
string[] statements =
{
"CREATE SEQUENCE Seq OPTIONS (sequence_kind = 'bit_reversed_positive')",
"CREATE TABLE Customers (CustomerId INT64 DEFAULT (GET_NEXT_SEQUENCE_VALUE(SEQUENCE Seq)), CustomerName STRING(1024)) PRIMARY KEY (CustomerId)"
};
var operation = await databaseAdminClient.UpdateDatabaseDdlAsync(databaseName, statements);
var completedResponse = await operation.PollUntilCompletedAsync();
if (completedResponse.IsFaulted)
{
throw completedResponse.Exception;
}
Console.WriteLine("Created Seq sequence and Customers table, where the key column CustomerId uses the sequence as a default value");
string connectionString = $"Data Source=projects/{projectId}/instances/{instanceId}/databases/{databaseId}";
using var connection = new SpannerConnection(connectionString);
await connection.OpenAsync();
using var cmd = connection.CreateDmlCommand(
@"INSERT INTO Customers (CustomerName) VALUES ('Alice'), ('David'), ('Marc') THEN RETURN CustomerId");
var reader = await cmd.ExecuteReaderAsync();
var customerIds = new List<long>();
while (await reader.ReadAsync())
{
var customerId = reader.GetFieldValue<long>("CustomerId");
Console.WriteLine($"Inserted customer record with CustomerId: {customerId}");
customerIds.Add(customerId);
}
Console.WriteLine($"Number of customer records inserted is: {customerIds.Count}");
return customerIds;
}
}Ir
import (
"context"
"fmt"
"io"
"cloud.google.com/go/spanner"
database "cloud.google.com/go/spanner/admin/database/apiv1"
adminpb "cloud.google.com/go/spanner/admin/database/apiv1/databasepb"
"google.golang.org/api/iterator"
)
func createSequence(w io.Writer, db string) error {
// db := "projects/my-project/instances/my-instance/databases/my-database"
ctx := context.Background()
adminClient, err := database.NewDatabaseAdminClient(ctx)
if err != nil {
return err
}
defer adminClient.Close()
// List of DDL statements to be applied to the database.
// Create a sequence, and then use the sequence as auto generated primary key in Customers table.
ddl := []string{
"CREATE SEQUENCE Seq OPTIONS (sequence_kind = 'bit_reversed_positive')",
"CREATE TABLE Customers (CustomerId INT64 DEFAULT (GET_NEXT_SEQUENCE_VALUE(Sequence Seq)), CustomerName STRING(1024)) PRIMARY KEY (CustomerId)",
}
op, err := adminClient.UpdateDatabaseDdl(ctx, &adminpb.UpdateDatabaseDdlRequest{
Database: db,
Statements: ddl,
})
if err != nil {
return err
}
// Wait for the UpdateDatabaseDdl operation to finish.
if err := op.Wait(ctx); err != nil {
return fmt.Errorf("waiting for bit reverse sequence creation to finish failed: %w", err)
}
fmt.Fprintf(w, "Created Seq sequence and Customers table, where the key column CustomerId uses the sequence as a default value\n")
client, err := spanner.NewClient(ctx, db)
if err != nil {
return err
}
defer client.Close()
// Inserts records into the Customers table.
// The ReadWriteTransaction function returns the commit timestamp and an error.
// The commit timestamp is ignored in this case.
_, err = client.ReadWriteTransaction(ctx, func(ctx context.Context, txn *spanner.ReadWriteTransaction) error {
stmt := spanner.Statement{
SQL: `INSERT INTO Customers (CustomerName) VALUES ('Alice'), ('David'), ('Marc') THEN RETURN CustomerId`,
}
iter := txn.Query(ctx, stmt)
defer iter.Stop()
for {
row, err := iter.Next()
if err == iterator.Done {
break
}
if err != nil {
return err
}
var customerId int64
if err := row.Columns(&customerId); err != nil {
return err
}
fmt.Fprintf(w, "Inserted customer record with CustomerId: %d\n", customerId)
}
fmt.Fprintf(w, "Number of customer records inserted is: %d\n", iter.RowCount)
return nil
})
return err
}
Java
import com.google.cloud.spanner.DatabaseClient;
import com.google.cloud.spanner.DatabaseId;
import com.google.cloud.spanner.ResultSet;
import com.google.cloud.spanner.Spanner;
import com.google.cloud.spanner.SpannerExceptionFactory;
import com.google.cloud.spanner.SpannerOptions;
import com.google.cloud.spanner.Statement;
import com.google.cloud.spanner.admin.database.v1.DatabaseAdminClient;
import com.google.common.collect.ImmutableList;
import com.google.spanner.admin.database.v1.DatabaseName;
import java.util.Objects;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
public class CreateSequenceSample {
static void createSequence() {
// TODO(developer): Replace these variables before running the sample.
final String projectId = "my-project";
final String instanceId = "my-instance";
final String databaseId = "my-database";
createSequence(projectId, instanceId, databaseId);
}
static void createSequence(String projectId, String instanceId, String databaseId) {
try (Spanner spanner =
SpannerOptions.newBuilder().setProjectId(projectId).build().getService();
DatabaseAdminClient databaseAdminClient = spanner.createDatabaseAdminClient()) {
databaseAdminClient
.updateDatabaseDdlAsync(
DatabaseName.of(projectId, instanceId, databaseId),
ImmutableList.of(
"CREATE SEQUENCE Seq OPTIONS (sequence_kind = 'bit_reversed_positive')",
"CREATE TABLE Customers (CustomerId INT64 DEFAULT "
+ "(GET_NEXT_SEQUENCE_VALUE(SEQUENCE Seq)), CustomerName STRING(1024)) "
+ "PRIMARY KEY (CustomerId)"))
.get(5, TimeUnit.MINUTES);
System.out.println(
"Created Seq sequence and Customers table, where the key column CustomerId "
+ "uses the sequence as a default value");
final DatabaseClient dbClient =
spanner.getDatabaseClient(DatabaseId.of(projectId, instanceId, databaseId));
Long insertCount =
dbClient
.readWriteTransaction()
.run(
transaction -> {
try (ResultSet rs =
transaction.executeQuery(
Statement.of(
"INSERT INTO Customers (CustomerName) VALUES "
+ "('Alice'), ('David'), ('Marc') THEN RETURN CustomerId"))) {
while (rs.next()) {
System.out.printf(
"Inserted customer record with CustomerId: %d\n", rs.getLong(0));
}
return Objects.requireNonNull(rs.getStats()).getRowCountExact();
}
});
System.out.printf("Number of customer records inserted is: %d\n", insertCount);
} catch (ExecutionException e) {
// If the operation failed during execution, expose the cause.
throw SpannerExceptionFactory.asSpannerException(e.getCause());
} catch (InterruptedException e) {
// Throw when a thread is waiting, sleeping, or otherwise occupied,
// and the thread is interrupted, either before or during the activity.
throw SpannerExceptionFactory.propagateInterrupt(e);
} catch (TimeoutException e) {
// If the operation timed out propagate the timeout
throw SpannerExceptionFactory.propagateTimeout(e);
}
}
}
Node.js
// Imports the Google Cloud client library.
const {Spanner} = require('@google-cloud/spanner');
/**
* TODO(developer): Uncomment the following lines before running the sample.
*/
// const projectId = 'my-project-id';
// const instanceId = 'my-instance';
// const databaseId = 'my-database';
// Creates a client
const spanner = new Spanner({
projectId: projectId,
});
async function createSequence(instanceId, databaseId) {
// Gets a reference to a Cloud Spanner Database Admin Client object
const databaseAdminClient = spanner.getDatabaseAdminClient();
const request = [
"CREATE SEQUENCE Seq OPTIONS (sequence_kind = 'bit_reversed_positive')",
'CREATE TABLE Customers (CustomerId INT64 DEFAULT (GET_NEXT_SEQUENCE_VALUE(Sequence Seq)), CustomerName STRING(1024)) PRIMARY KEY (CustomerId)',
];
// Creates a new table with sequence
try {
const [operation] = await databaseAdminClient.updateDatabaseDdl({
database: databaseAdminClient.databasePath(
projectId,
instanceId,
databaseId,
),
statements: request,
});
console.log('Waiting for operation to complete...');
await operation.promise();
console.log(
'Created Seq sequence and Customers table, where the key column CustomerId uses the sequence as a default value.',
);
} catch (err) {
console.error('ERROR:', err);
}