Generate CSV from SQL
Visulate for Oracle allows users to run ad-hoc queries via the UI or API calls. The UI exposes a query editor when the user selects a schema in a registered database. The query editor region is collapsed by default unless the user has navigated to a table or view. Clicking on the title area of the region toggles its visibility.
The expanded region displays an HTML form with username, password, sql query, bind variables and query option fields. Most of the fields are populated with default values when the user navigates to a table or view.
Entering the database password for the schema where the table resides to enables the Run Query
button. Pressing this button causes an HTTP POST request to be made to the SQL Query endpoint passing the SQL statement and database credentials. The SQL Query Engine makes a database connection, executes the query and then closes the connection.
Results are displayed in an HTML table. A curl command appears below the results. These show the syntax to use in a console window to execute REST API calls outside of the UI.
Note: Database credentials are passed to the SQL Query Engine using a basic auth header. Make sure you are using a secure (https) connection before submitting a query.
Bind Variables
The query engine supports bind variable substitution. Bind variables can be included in the SQL Query using a colon (:) prefix.
The default query that appears on table or view selection shows an example. When the user navigates to a table or view the SQL Query field is populate with a default query in the form:
select * from [TABLE_NAME] where rownum < :maxrows
:maxrows
is a bind variable in this query. A value for it must be supplied via the Bind Variables field for the query to run. The UI populates a default value of 10 {"maxrows": 10 }
for this. This limits the number of rows that the query will return. Passing a different value will increase or reduce the number of rows returned.
Bind variables can be passed as an object e.g. {"maxrows": 10 }
or an array [10]
.
The SQL Query and Bind Variables field values must match. An error “400 Bad Request: ORA-01008: not all variables bound” is returned if there are bind variables in the query that do not have corresponding values. A separate error “400 Bad Request: ORA-01036: illegal variable name/number” is returned if a bind variable is passed that does not have a placeholder in the query.
Query Options
The query engine supports 3 optional arguments to modify its behavior:
- download_lobs
- csv_header
- cx_oracle_object
These are passed as an object e.g. {"download_lobs": "N", "csv_header": "N", "cx_oracle_object": "MDSYS.SDO_GEOMETRY"}
download_lobs
By default the query engine returns a character string with the LOB size rather than the actual content for queries that include a CLOB or BLOB column. This behavior can be modified by passing a value of “Y” for the download_lobs option. This will cause the query engine to return CLOB and BLOB values in the results as long as the values do not exceed 1 GB in length. BLOB values base64 encoded prior to download.
Note: An error is returned for rows with LOBs that exceed 1 GB in length if the download_lobs option is set to “Y”.
csv_header
The csv_header option includes or excludes the generation of a header row in the results with column names from the query. It affects the CSV file contents returned from the REST API (e.g. via curl). The UI ignores this parameter.
cx_oracle_object
By default the query engine lists the object type rather than attempting to display its contents for queries that include Oracle object type columns. For example, the following query includes a spatial column called GEOM:
curl -L 'https://visulate.mycorp.com/sql/vis13'
-H 'Authorization: Basic dkjkjadiDDDwiidjf'
-H 'Content-Type: application/json'
-H 'Accept: text/csv'
-d @- << EOF
{ "sql": "select parcelno, geom from PR_GEO where rownum < :maxrows",
"binds": {"maxrows": 2 },
"options": {"download_lobs": "N", "csv_header": "Y"}
}
EOF
"PARCELNO","GEOM"
"00000000-19-1075-0013","<cx_Oracle.Object MDSYS.SDO_GEOMETRY at 0x7f22557c9c70>"
The query engine returned “<cx_Oracle.Object MDSYS.SDO_GEOMETRY at 0x7f22557c9c70>” as a value for GEOM indicating an object type of MDSYS.SDO_GEOMETRY for the column. Passing "cx_oracle_object": "MDSYS.SDO_GEOMETRY"
as a query option causes the query engine to parse the spatial column and return its value:
curl -L 'https://visulate.mycorp.com/sql/vis13'
-H 'Authorization: Basic dkjkjadiDDDwiidjf'
-H 'Content-Type: application/json'
-H 'Accept: text/csv'
-d @- << EOF
{ "sql": "select parcelno, geom from PR_GEO where rownum < :maxrows",
"binds": {"maxrows": 2 },
"options": {"download_lobs": "N", "csv_header": "Y", "cx_oracle_object": "MDSYS.SDO_GEOMETRY"}
}
EOF
"PARCELNO","GEOM"
"00000000-19-1075-0013"," {
SDO_GTYPE: 3
SDO_SRID: 8307
SDO_POINT: None
SDO_ELEM_INFO:
[
1
3
1
]
SDO_ORDINATES:
[
-85.6198436336
30.530487272
-85.6200461878
30.5303544724
-85.6204100845
30.5307704037
-85.6202075298
30.5309031996
-85.6198436336
30.530487272
]
}
"
Note: The query engine only allows one object type per query
CSV file generation
Use the UI to develop and test queries for CSV file generation then cut and paste the curl statement to generate files. Examples:
Download to file:
curl \
-L 'https://visulate.mycorp.com/sql/vis13' \
-H 'Authorization: Basic dkjkjadiDDDwiidjf' \
-H 'Content-Type: application/json' \
-H 'Accept: text/csv' \
-o pr_property_geo.csv \
-d @- << EOF
{ "sql": "select *
from PR_PROPERTIES p
, PR_GEO g
where p.prop_id = g.prop_id",
"binds": {},
"options": {"download_lobs": "N", "cx_oracle_object": "MDSYS.SDO_GEOMETRY"}
}
EOF
Stream to Google Cloud Storage:
curl \
-L 'https://visulate.mycorp.com/sql/vis13' \
-H 'Authorization: Basic dkjkjadiDDDwiidjf' \
-H 'Content-Type: application/json' \
-H 'Accept: text/csv' \
-d @- << EOF | gsutil cp - gs://bigquery-geo/pr_property_geo.csv
{ "sql": "select *
from PR_PROPERTIES p
, PR_GEO g
where p.prop_id = g.prop_id",
"binds": {},
"options": {"download_lobs": "N", "cx_oracle_object": "MDSYS.SDO_GEOMETRY"}
}
EOF
JSON file generation
Change the http request header Accept
value from test/csv to application/json to generate JSON instead of CSV output.
Timeout behavior
Long running queries may timeout before completion. The default setting for this is 30 seconds. The query engine config guide includes instructions on how to change this.
Security considerations
- Access to this feature can be controlled by a configuration file. This allows an admin to limit the list of database environments that allow query access. For example, they may wish to allow access for development databases but not production. See The query engine config guide for details.
- Database credentials are passed to the SQL Query Engine using a basic auth header. It should only be used via a secure (https) connection.