Verarbeitung der Abfrageergebnisse der Amazon RDS Data API im JSON-Format - Amazon Aurora

Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.

Verarbeitung der Abfrageergebnisse der Amazon RDS Data API im JSON-Format

Wenn Sie die ExecuteStatement-Operation aufrufen, können Sie auswählen, ob die Abfrageergebnisse als Zeichenfolge im JSON-Format zurückgegeben werden sollen. Auf diese Weise können Sie die JSON-Parsing-Funktionen Ihrer Programmiersprache verwenden, um die Ergebnismenge zu interpretieren und neu zu formatieren. Dies kann dazu beitragen, zu vermeiden, zusätzlichen Code zu schreiben, um die Ergebnismenge zu durchlaufen und jeden Spaltenwert zu interpretieren.

Zum Anfordern der Ergebnismenge im JSON-Format übergeben Sie den optionalen formatRecordsAs-Parameter mit dem Wert JSON. Die JSON-formatierte Ergebnismenge wird im Feld formattedRecords der ExecuteStatementResponse-Struktur zurückgegeben.

Die BatchExecuteStatement-Aktion gibt keine Ergebnismenge zurück. Daher gilt die JSON-Option nicht für diese Aktion.

Wenn Sie die Schlüssel in der JSON-Hash-Struktur anpassen möchten, definieren Sie Spaltenaliasnamen in der Ergebnismenge. Verwenden Sie dazu die AS-Klausel in der Spaltenliste Ihrer SQL-Abfrage.

Sie können die JSON-Funktion verwenden, um die Ergebnismenge besser lesbar zu machen und den Inhalt sprachspezifischen Frameworks zuzuordnen. Da das Volume der ASCII-kodierten Ergebnismenge größer als die Standarddarstellung ist, können Sie die Standarddarstellung für Abfragen auswählen, die eine große Anzahl von Zeilen oder große Spaltenwerte zurückgeben, die mehr Speicher belegen, als für Ihre Anwendung verfügbar ist.

Abrufen von Abfrageergebnissen im JSON-Format

Um die Ergebnismenge als JSON-Zeichenfolge zu erhalten, fügen Sie sie .withFormatRecordsAs(RecordsFormatType.JSON) in den ExecuteStatement Aufruf ein. Der Rückgabewert wird im Feld formattedRecords als JSON-Zeichenfolge angezeigt. In diesem Fall hat columnMetadata den Wert null. Die Spaltenbeschriftungen sind die Schlüssel des Objekts, das jede Zeile darstellt. Diese Spaltennamen werden für jede Zeile in der Ergebnismenge wiederholt. Die Spaltenwerte sind in Anführungszeichen gesetzte Zeichenfolgen, numerische Werte oder Sonderwerte, die true, false oder null darstellen. Spaltenmetadaten wie Längenbeschränkungen und der genaue Typ für Zahlen und Zeichenfolgen werden in der JSON-Antwort nicht beibehalten.

Wenn Sie den .withFormatRecordsAs()-Aufruf weglassen oder einen Parameter NONE angeben, wird die Ergebnismenge im Binärformat unter Verwendung der Felder Records und columnMetadata zurückgegeben.

Datentypenzuordnung

Die SQL-Werte in der Ergebnismenge werden einem kleineren Satz von JSON-Typen zugeordnet. Die Werte werden in JSON als Zeichenfolgen, Zahlen und einige spezielle Konstanten wie true, false und null dargestellt. Sie können diese Werte in Variablen in Ihrer Anwendung umwandeln, indem Sie eine starke oder schwache Eingabe verwenden, die für Ihre Programmiersprache geeignet ist.

JDBC-Datentyp

JSON-Datentyp

INTEGER, TINYINT, SMALLINT, BIGINT

Die Standardeinstellung ist Zahl. Zeichenfolge, wenn die Option LongReturnType auf STRING eingestellt ist.

FLOAT, REAL, DOUBLE

Anzahl

DECIMAL

Die Standardeinstellung ist Zeichenfolge. Zahl, wenn die Option DecimalReturnType auf DOUBLE_OR_LONG eingestellt ist.

STRING

String

BOOLEAN, BIT

Boolesch

BLOB, BINARY, VARBINARY, LONGVARBINARY

Zeichenfolge in Base64-Kodierung.

CLOB

String

ARRAY

Array

NULL

null

Andere Typen (einschließlich datums- und zeitbezogener Typen)

String

Fehlerbehebung

Die JSON-Antwort ist auf 10 Megabyte begrenzt. Wenn die Antwort größer als dieses Limit ist, erhält Ihr Programm einen BadRequestException-Fehler. In diesem Fall können Sie den Fehler mit einer der folgenden Methoden beheben:

  • Reduzieren Sie die Anzahl der Zeilen in der Ergebnismenge. Fügen Sie dazu eine LIMIT-Klausel hinzu. Sie können eine große Ergebnismenge in mehrere kleinere aufteilen, indem Sie mehrere Abfragen mit den Klauseln LIMIT und OFFSET senden.

    Wenn die Ergebnismenge Zeilen enthält, die durch die Anwendungslogik herausgefiltert werden, können Sie diese Zeilen aus der Ergebnismenge entfernen, indem Sie der WHERE-Klausel weitere Bedingungen hinzufügen.

  • Reduzieren Sie die Anzahl der Spalten in der Ergebnismenge. Entfernen Sie dazu Elemente aus der Auswahlliste der Abfrage.

  • Verkürzen Sie die Spaltenbeschriftungen, indem Sie Spaltenaliasnamen in der Abfrage verwenden. Jeder Spaltenname wird in der JSON-Zeichenfolge für jede Zeile der Ergebnismenge wiederholt. Daher könnte ein Abfrageergebnis mit langen Spaltennamen und vielen Zeilen die Größenbeschränkung überschreiten. Verwenden Sie insbesondere Spaltenaliasnamen für komplizierte Ausdrücke, um zu vermeiden, dass der gesamte Ausdruck in der JSON-Zeichenfolge wiederholt wird.

  • Während Sie mit SQL Spaltenaliasnamen verwenden können, um eine Ergebnismenge mit mehr als einer Spalte mit demselben Namen zu erzeugen, sind doppelte Schlüsselnamen in JSON nicht zulässig. Die RDS-Daten-API gibt einen Fehler zurück, wenn Sie die Ergebnismenge im JSON-Format anfordern und mehr als eine Spalte denselben Namen hat. Stellen Sie daher sicher, dass alle Spaltenbeschriftungen eindeutige Namen haben.

Beispiele

Die folgenden Java-Beispiele zeigen, wie Sie ExecuteStatement mit der Antwort als JSON-formatierte Zeichenfolge aufrufen und dann die Ergebnismenge interpretieren. Ersetzen Sie die clusterArn Parameter databaseNamesecretStoreArn, und durch die entsprechenden Werte.

Das folgende Java-Beispiel veranschaulicht eine Abfrage, die einen numerischen Dezimalwert in der Ergebnismenge zurückgibt. assertThat-Aufrufe testen anhand der Regeln für JSON-Ergebnismengen, ob die Felder der Antwort die erwarteten Eigenschaften haben.

Dieses Beispiel funktioniert mit dem folgenden Schema und den folgenden Beispieldaten:

create table test_simplified_json (a float); insert into test_simplified_json values(10.0);
public void JSON_result_set_demo() { var sql = "select * from test_simplified_json"; var request = new ExecuteStatementRequest() .withDatabase(databaseName) .withSecretArn(secretStoreArn) .withResourceArn(clusterArn) .withSql(sql) .withFormatRecordsAs(RecordsFormatType.JSON); var result = rdsdataClient.executeStatement(request); }

Der Wert des Felds formattedRecords aus dem vorhergehenden Programm lautet:

[{"a":10.0}]

Die Felder Records und ColumnMetadata in der Antwort sind aufgrund des Vorhandenseins der JSON-Ergebnismenge beide null.

Das folgende Java-Beispiel veranschaulicht eine Abfrage, die einen numerischen Ganzzahlwert in der Ergebnismenge zurückgibt. Das Beispiel ruft getFormattedRecords auf, um nur die JSON-formatierte Zeichenfolge zurückzugeben und die anderen Antwortfelder zu ignorieren, die leer oder null sind. Im Beispiel wird das Ergebnis in eine Struktur deserialisiert, die eine Liste von Datensätzen darstellt. Jeder Datensatz enthält Felder, deren Namen den Spaltenaliasnamen aus der Ergebnismenge entsprechen. Diese Methode vereinfacht den Code, der die Ergebnismenge analysiert. Ihre Anwendung muss nicht die Zeilen und Spalten der Ergebnismenge durchlaufen und jeden Wert in den entsprechenden Typ konvertieren.

Dieses Beispiel funktioniert mit dem folgenden Schema und den folgenden Beispieldaten:

create table test_simplified_json (a int); insert into test_simplified_json values(17);
public void JSON_deserialization_demo() { var sql = "select * from test_simplified_json"; var request = new ExecuteStatementRequest() .withDatabase(databaseName) .withSecretArn(secretStoreArn) .withResourceArn(clusterArn) .withSql(sql) .withFormatRecordsAs(RecordsFormatType.JSON); var result = rdsdataClient.executeStatement(request) .getFormattedRecords(); /* Turn the result set into a Java object, a list of records. Each record has a field 'a' corresponding to the column labelled 'a' in the result set. */ private static class Record { public int a; } var recordsList = new ObjectMapper().readValue( response, new TypeReference<List<Record>>() { }); }

Der Wert des Felds formattedRecords aus dem vorhergehenden Programm lautet:

[{"a":17}]

Zum Abrufen der Spalte a der Ergebniszeile 0 würde sich die Anwendung auf recordsList.get(0).a beziehen.

Im Gegensatz dazu zeigt das folgende Java-Beispiel die Art von Code, der zum Erstellen einer Datenstruktur erforderlich ist, die die Ergebnismenge enthält, wenn Sie das JSON-Format nicht verwenden. In diesem Fall enthält jede Zeile der Ergebnismenge Felder mit Informationen über einen einzelnen Benutzer. Das Erstellen einer Datenstruktur zur Darstellung der Ergebnismenge erfordert das Durchlaufen der Zeilen. Für jede Zeile ruft der Code den Wert jedes Felds ab, führt eine entsprechende Typkonvertierung durch und weist das Ergebnis dem entsprechenden Feld im Objekt zu, das die Zeile darstellt. Dann fügt der Code das Objekt, das jeden Benutzer repräsentiert, der Datenstruktur hinzu, die die gesamte Ergebnismenge darstellt. Wenn die Abfrage geändert wurde, um Felder in der Ergebnismenge neu anzuordnen, hinzuzufügen oder zu entfernen, müsste sich der Anwendungscode ebenfalls ändern.

/* Verbose result-parsing code that doesn't use the JSON result set format */ for (var row: response.getRecords()) { var user = User.builder() .userId(row.get(0).getLongValue()) .firstName(row.get(1).getStringValue()) .lastName(row.get(2).getStringValue()) .dob(Instant.parse(row.get(3).getStringValue())) .build(); result.add(user); }

Die folgenden Beispielwerte zeigen die Werte des Felds formattedRecords für Ergebnismengen mit unterschiedlicher Anzahl von Spalten, Spaltenaliasnamen und Spaltendatentypen.

Wenn die Ergebnismenge mehrere Zeilen enthält, wird jede Zeile als Objekt dargestellt, das ein Array-Element ist. Jede Spalte in der Ergebnismenge wird zu einem Schlüssel im Objekt. Die Schlüssel werden für jede Zeile in der Ergebnismenge wiederholt. Daher müssen Sie für Ergebnismengen, die aus vielen Zeilen und Spalten bestehen, möglicherweise kurze Spaltenaliasnamen definieren, um zu vermeiden, dass das Längenlimit für die gesamte Antwort überschritten wird.

Dieses Beispiel funktioniert mit dem folgenden Schema und den folgenden Beispieldaten:

create table sample_names (id int, name varchar(128)); insert into sample_names values (0, "Jane"), (1, "Mohan"), (2, "Maria"), (3, "Bruce"), (4, "Jasmine");
[{"id":0,"name":"Jane"},{"id":1,"name":"Mohan"}, {"id":2,"name":"Maria"},{"id":3,"name":"Bruce"},{"id":4,"name":"Jasmine"}]

Wenn eine Spalte in der Ergebnismenge als Ausdruck definiert ist, wird der Text des Ausdrucks zum JSON-Schlüssel. Daher ist es normalerweise praktisch, einen beschreibenden Spaltenalias für jeden Ausdruck in der Auswahlliste der Abfrage zu definieren. Die folgende Abfrage enthält beispielsweise Ausdrücke wie Funktionsaufrufe und arithmetische Operationen in ihrer Auswahlliste.

select count(*), max(id), 4+7 from sample_names;

Diese Ausdrücke werden als Schlüssel an die JSON-Ergebnismenge übergeben.

[{"count(*)":5,"max(id)":4,"4+7":11}]

Wenn Sie AS-Spalten mit beschreibenden Beschriftungen hinzufügen, können die Schlüssel in der JSON-Ergebnismenge einfacher interpretiert werden.

select count(*) as rows, max(id) as largest_id, 4+7 as addition_result from sample_names;

Bei der überarbeiteten SQL-Abfrage werden die Spaltenbeschriftungen, die durch die AS-Klauseln definiert werden, als Schlüsselnamen verwendet.

[{"rows":5,"largest_id":4,"addition_result":11}]

Der Wert für jedes Schlüssel-Wert-Paar in der JSON-Zeichenfolge kann eine Zeichenfolge in Anführungszeichen sein. Die Zeichenfolge enthält möglicherweise Unicode-Zeichen. Wenn die Zeichenfolge Escape-Sequenzen oder die Zeichen " oder \ enthält, wird diesen Zeichen ein Escape-Zeichen mit umgekehrtem Schrägstrich vorangestellt. Die folgenden Beispiele für JSON-Zeichenfolgen veranschaulichen diese Möglichkeiten. Das Ergebnis string_with_escape_sequences enthält z. B. die Sonderzeichen Rücktaste, Zeilenumbruch, Wagenrücklauf, Tabulator, Seitenvorschub und \.

[{"quoted_string":"hello"}] [{"unicode_string":"邓不利多"}] [{"string_with_escape_sequences":"\b \n \r \t \f \\ '"}]

Der Wert für jedes Schlüssel-Wert-Paar in der JSON-Zeichenfolge kann auch eine Zahl darstellen. Die Zahl kann eine Ganzzahl, ein Gleitkommawert, ein negativer Wert oder ein Wert sein, der in Exponentialschreibweise dargestellt wird. Die folgenden Beispiele für JSON-Zeichenfolgen veranschaulichen diese Möglichkeiten.

[{"integer_value":17}] [{"float_value":10.0}] [{"negative_value":-9223372036854775808,"positive_value":9223372036854775807}] [{"very_small_floating_point_value":4.9E-324,"very_large_floating_point_value":1.7976931348623157E308}]

Boolesche und Nullwerte werden mit den Sonderschlüsselwörtern true, false und null ohne Anführungszeichen dargestellt. Die folgenden Beispiele für JSON-Zeichenfolgen veranschaulichen diese Möglichkeiten.

[{"boolean_value_1":true,"boolean_value_2":false}] [{"unknown_value":null}]

Wenn Sie einen Wert eines BLOB-Typs auswählen, wird das Ergebnis in der JSON-Zeichenfolge als Base64-kodierter Wert dargestellt. Wenn Sie den Wert wieder in seine ursprüngliche Darstellung umwandeln möchten, können Sie die entsprechende Dekodierungsfunktion in der Sprache Ihrer Anwendung verwenden. In Java rufen Sie beispielsweise die Funktion Base64.getDecoder().decode() auf. Die folgende Beispielausgabe zeigt das Ergebnis der Auswahl des BLOB-Werts hello world und gibt die Ergebnismenge als JSON-Zeichenfolge zurück.

[{"blob_column":"aGVsbG8gd29ybGQ="}]

Das folgende Python-Beispiel zeigt, wie Sie auf die Werte aus dem Ergebnis eines Aufrufs der Python-Funktion execute_statement zugreifen. Die Ergebnismenge ist ein Zeichenfolgenwert im Feld response['formattedRecords']. Der Code verwandelt die JSON-Zeichenfolge durch Aufrufen der Funktion json.loads in eine Datenstruktur. Dann ist jede Zeile der Ergebnismenge ein Listenelement innerhalb der Datenstruktur und innerhalb jeder Zeile können Sie auf jedes Feld der Ergebnismenge nach Namen verweisen.

import json result = json.loads(response['formattedRecords']) print (result[0]["id"])

Das folgende JavaScript Beispiel zeigt, wie Sie auf die Werte aus dem Ergebnis eines JavaScript executeStatement Funktionsaufrufs zugreifen können. Die Ergebnismenge ist ein Zeichenfolgenwert im Feld response.formattedRecords. Der Code verwandelt die JSON-Zeichenfolge durch Aufrufen der Funktion JSON.parse in eine Datenstruktur. Dann ist jede Zeile der Ergebnismenge ein Array-Element innerhalb der Datenstruktur und innerhalb jeder Zeile können Sie auf jedes Feld der Ergebnismenge nach Namen verweisen.

<script> const result = JSON.parse(response.formattedRecords); document.getElementById("display").innerHTML = result[0].id; </script>