SYSDATE or CURRENT_DATE
DATE
format that always returns a date in ISO 8601 format. DATE_FROM_UNIX_DATE
can't be used because it is 1970-based.
CURRENT_DATE-3
DATE_ADD
() or DATE_SUB
(). BigQuery uses arithmetic operators for data types: INT64
, NUMERIC
, and FLOAT64
. NLS_DATE_FORMAT
This section addresses differences in query syntax between Oracle and BigQuery.
SELECT
statementsMost Oracle SELECT
statements are compatible with BigQuery.
The following sections list mappings between Oracle functions and BigQuery equivalents.
Oracle and BigQuery comparison operators are ANSI SQL:2011 compliant. The comparison operators in the table below are the same in both BigQuery and Oracle. You can use REGEXP_CONTAINS
instead of REGEXP_LIKE
in BigQuery.
Operator | Description |
---|---|
"=" | Equal |
<> | Not equal |
!= | Not equal |
> | Greater than |
>= | Greater than or equal |
< | Less than |
<= | Less than or equal |
IN ( ) | Matches a value in a list |
NOT | Negates a condition |
BETWEEN | Within a range (inclusive) |
IS NULL | NULL value |
IS NOT NULL | Not NULL value |
LIKE | Pattern matching with % |
EXISTS | Condition is met if subquery returns at least one row |
The operators on the table are the same both in BigQuery and Oracle.
The following table shows mappings between common Oracle aggregate, statistical aggregate, and approximate aggregate functions with their BigQuery equivalents:
Oracle | BigQuery |
---|---|
ANY_VALUE (from Oracle 19c) | ANY_VALUE |
APPROX_COUNT | HLL_COUNT set of functions with specified precision |
APPROX_COUNT_DISTINCT | APPROX_COUNT_DISTINCT |
APPROX_COUNT_DISTINCT_AGG | APPROX_COUNT_DISTINCT |
APPROX_COUNT_DISTINCT_DETAIL | APPROX_COUNT_DISTINCT |
APPROX_PERCENTILE(percentile) WITHIN GROUP (ORDER BY expression) | APPROX_QUANTILES(expression, 100)[ BigQuery doesn't support the rest of arguments that Oracle defines. |
APPROX_PERCENTILE_AGG | APPROX_QUANTILES(expression, 100)[ |
APPROX_PERCENTILE_DETAIL | APPROX_QUANTILES(expression, 100)[OFFSET(CAST(TRUNC(percentile * 100) as INT64))] |
APPROX_SUM | APPROX_TOP_SUM(expression, weight, number) |
AVG | AVG |
BIT_COMPLEMENT | bitwise not operator: ~ |
BIT_OR | BIT_OR, X | Y |
BIT_XOR | BIT_XOR, X ^ Y |
BITAND | BIT_AND, X & Y |
CARDINALITY | COUNT |
COLLECT | BigQuery doesn't support TYPE AS TABLE OF . Consider using STRING_AGG() or ARRAY_AGG() in BigQuery |
CORR/CORR_K/ CORR_S | CORR |
COUNT | COUNT |
COVAR_POP | COVAR_POP |
COVAR_SAMP | COVAR_SAMP |
FIRST | Does not exist implicitly in BigQuery. Consider using user-defined functions (UDFs). |
GROUP_ID | Not used in BigQuery |
GROUPING | Not used in BigQuery |
GROUPING_ID | Not used in BigQuery. |
LAST | Does not exist implicitly in BigQuery. Consider using UDFs. |
LISTAGG | STRING_AGG, ARRAY_CONCAT_AGG(expression [ORDER BY key [{ASC|DESC}] [, ... ]] [LIMIT n]) |
MAX | MAX |
MIN | MIN |
OLAP_CONDITION | Oracle specific, does not exist in BigQuery. |
OLAP_EXPRESSION | Oracle specific, does not exist in BigQuery. |
OLAP_EXPRESSION_BOOL | Oracle specific, does not exist in BigQuery. |
OLAP_EXPRESSION_DATE | Oracle specific, does not exist in BigQuery. |
OLAP_EXPRESSION_TEXT | Oracle specific, does not exist in BigQuery. |
OLAP_TABLE | Oracle specific, does not exist in BigQuery. |
POWERMULTISET | Oracle specific, does not exist in BigQuery. |
POWERMULTISET_BY_CARDINALITY | Oracle specific, does not exist in BigQuery. |
QUALIFY | Oracle specific, does not exist in BigQuery. |
REGR_AVGX | AVG( IF(dep_var_expr is NULL OR ind_var_expr is NULL, NULL, ind_var_expr) ) |
REGR_AVGY | AVG( IF(dep_var_expr is NULL OR ind_var_expr is NULL, NULL, dep_var_expr) ) |
REGR_COUNT | SUM( IF(dep_var_expr is NULL OR ind_var_expr is NULL, NULL, 1) ) |
REGR_INTERCEPT | AVG(dep_var_expr) |
REGR_R2 | (COUNT(dep_var_expr) * |
REGR_SLOPE | COVAR_SAMP(ind_var_expr,
|
REGR_SXX | SUM(POWER(ind_var_expr, 2)) - COUNT(ind_var_expr) * POWER(AVG(ind_var_expr),2) |
REGR_SXY | SUM(ind_var_expr*dep_var_expr) - COUNT(ind_var_expr) * AVG(ind) * AVG(dep_var_expr) |
REGR_SYY | SUM(POWER(dep_var_expr, 2)) - COUNT(dep_var_expr) * POWER(AVG(dep_var_expr),2) |
ROLLUP | ROLLUP |
STDDEV_POP | STDDEV_POP |
STDDEV_SAMP | STDDEV_SAMP, STDDEV |
SUM | SUM |
VAR_POP | VAR_POP |
VAR_SAMP | VAR_SAMP, VARIANCE |
WM_CONCAT | STRING_AGG |
BigQuery offers the following additional aggregate functions:
The following table shows mappings between common Oracle analytic and aggregate analytic functions with their BigQuery equivalents.
Oracle | BigQuery |
---|---|
AVG | AVG |
BIT_COMPLEMENT | bitwise not operator: ~ |
BIT_OR | BIT_OR, X | Y |
BIT_XOR | BIT_XOR, X ^ Y |
BITAND | BIT_AND, X & Y |
BOOL_TO_INT | CAST(X AS INT64) |
COUNT | COUNT |
COVAR_POP | COVAR_POP |
COVAR_SAMP | COVAR_SAMP |
CUBE_TABLE | Isn't supported in BigQuery. Consider using a BI tool or a custom UDF |
CUME_DIST | CUME_DIST |
DENSE_RANK(ANSI) | DENSE_RANK |
FEATURE_COMPARE | Does not exist implicitly in BigQuery. Consider using UDFs and BigQuery ML |
FEATURE_DETAILS | Does not exist implicitly in BigQuery. Consider using UDFs and BigQuery ML |
FEATURE_ID | Does not exist implicitly in BigQuery. Consider using UDFs and BigQuery ML |
FEATURE_SET | Does not exist implicitly in BigQuery. Consider using UDFs and BigQuery ML |
FEATURE_VALUE | Does not exist implicitly in BigQuery. Consider using UDFs and BigQuery ML |
FIRST_VALUE | FIRST_VALUE |
HIER_CAPTION | Hierarchical queries are not supported in BigQuery. |
HIER_CHILD_COUNT | Hierarchical queries are not supported in BigQuery. |
HIER_COLUMN | Hierarchical queries are not supported in BigQuery. |
HIER_DEPTH | Hierarchical queries are not supported in BigQuery. |
HIER_DESCRIPTION | Hierarchical queries are not supported in BigQuery. |
HIER_HAS_CHILDREN | Hierarchical queries are not supported in BigQuery. |
HIER_LEVEL | Hierarchical queries are not supported in BigQuery. |
HIER_MEMBER_NAME | Hierarchical queries are not supported in BigQuery. |
HIER_ORDER | Hierarchical queries are not supported in BigQuery. |
HIER_UNIQUE_MEMBER_NAME | Hierarchical queries are not supported in BigQuery. |
LAST_VALUE | LAST_VALUE |
LAG | LAG |
LEAD | LEAD |
LISTAGG | ARRAY_AGG |
MATCH_NUMBER | Pattern recognition and calculation can be done with regular expressions and UDFs in BigQuery |
MATCH_RECOGNIZE | Pattern recognition and calculation can be done with regular expressions and UDFs in BigQuery |
MAX | MAX |
MEDIAN | PERCENTILE_CONT(x, 0.5 RESPECT NULLS) OVER() |
MIN | MIN |
NTH_VALUE | NTH_VALUE (value_expression, constant_integer_expression [{RESPECT | IGNORE} NULLS]) |
NTILE | NTILE(constant_integer_expression) |
PERCENT_RANK | PERCENT_RANK |
PERCENTILE_CONT | PERCENTILE_CONT |
PERCENTILE_CONT | PERCENTILE_DISC |
PRESENTNNV | Oracle specific, does not exist in BigQuery. |
PRESENTV | Oracle specific, does not exist in BigQuery. |
PREVIOUS | Oracle specific, does not exist in BigQuery. |
RANK (ANSI) | RANK |
RATIO_TO_REPORT(expr) OVER (partition clause) | expr / SUM(expr) OVER (partition clause) |
ROW_NUMBER | ROW_NUMBER |
STDDEV_POP | STDDEV_POP |
STDDEV_SAMP | STDDEV_SAMP, STDDEV |
SUM | SUM |
VAR_POP | VAR_POP |
VAR_SAMP | VAR_SAMP, VARIANCE |
VARIANCE | VARIANCE() |
WIDTH_BUCKET | UDF can be used. |
The following table shows mappings between common Oracle date/time functions and their BigQuery equivalents.
Oracle | BigQuery |
---|---|
ADD_MONTHS(date, integer) | DATE_ADD(date, INTERVAL integer MONTH), If date is a TIMESTAMP you can use
|
CURRENT_DATE | CURRENT_DATE |
CURRENT_TIME | CURRENT_TIME |
CURRENT_TIMESTAMP | CURRENT_TIMESTAMP |
DATE - k | DATE_SUB(date_expression, INTERVAL k DAY) |
DATE + k | DATE_ADD(date_expression, INTERVAL k DAY) |
DBTIMEZONE | BigQuery does not support the database time zone. |
EXTRACT | EXTRACT(DATE), EXTRACT(TIMESTAMP) |
LAST_DAY | DATE_SUB( |
LOCALTIMESTAMP | BigQuery doesn't support time zone settings. |
MONTHS_BETWEEN | DATE_DIFF(date_expression, date_expression, MONTH) |
NEW_TIME | DATE(timestamp_expression, time zone) |
NEXT_DAY | DATE_ADD( |
SYS_AT_TIME_ZONE | CURRENT_DATE([time_zone]) |
SYSDATE | CURRENT_DATE() |
SYSTIMESTAMP | CURRENT_TIMESTAMP() |
TO_DATE | PARSE_DATE |
TO_TIMESTAMP | PARSE_TIMESTAMP |
TO_TIMESTAMP_TZ | PARSE_TIMESTAMP |
TZ_OFFSET | Isn't supported in BigQuery. Consider using a custom UDF. |
WM_CONTAINS WM_EQUALS WM_GREATERTHAN WM_INTERSECTION WM_LDIFF WM_LESSTHAN WM_MEETS WM_OVERLAPS WM_RDIFF | Periods are not used in BigQuery. UDFs can be used to compare two periods. |
BigQuery offers the following additional date/time functions:
CURRENT_DATETIME
DATE_FROM_UNIX_DATE
DATE_TRUNC
DATETIME
DATETIME_ADD
DATETIME_DIFF
DATETIME_SUB
DATETIME_TRUNC
FORMAT_DATE
FORMAT_DATETIME
The following table shows mappings between Oracle string functions and their BigQuery equivalents:
Oracle | BigQuery |
---|---|
ASCII | TO_CODE_POINTS(string_expr)[OFFSET(0)] |
ASCIISTR | BigQuery doesn't support UTF-16 |
RAWTOHEX | TO_HEX |
LENGTH | CHAR_LENGTH |
LENGTH | CHARACTER_LENGTH |
CHR | CODE_POINTS_TO_STRING( |
COLLATION | Doesn't exist in BigQuery. BigQuery doesn't support COLLATE in DML |
COMPOSE | Custom user-defined function. |
CONCAT, (|| operator) | CONCAT |
DECOMPOSE | Custom user-defined function. |
ESCAPE_REFERENCE (UTL_I18N) | Is not supported in BigQuery. Consider using a user-defined function. |
INITCAP | INITCAP |
INSTR/INSTR2/INSTR4/INSTRB/INSTRC | Custom user-defined function. |
LENGTH/LENGTH2/LENGTH4/LENGTHB/LENGTHC | LENGTH |
LOWER | LOWER |
LPAD | LPAD |
LTRIM | LTRIM |
NLS_INITCAP | Custom user-defined function. |
NLS_LOWER | LOWER |
NLS_UPPER | UPPER |
NLSSORT | Oracle specific, does not exist in BigQuery. |
POSITION | STRPOS(string, substring) |
PRINTBLOBTOCLOB | Oracle specific, does not exist in BigQuery. |
REGEXP_COUNT | ARRAY_LENGTH(REGEXP_EXTRACT_ALL(value, regex)) |
REGEXP_INSTR | STRPOS(source_string, REGEXP_EXTRACT(source_string, regexp_string)) Note: Returns first occurrence. |
REGEXP_REPLACE | REGEXP_REPLACE |
REGEXP_LIKE | IF(REGEXP_CONTAINS,1,0) |
REGEXP_SUBSTR | REGEXP_EXTRACT, REGEXP_EXTRACT_ALL |
REPLACE | REPLACE |
REVERSE | REVERSE |
RIGHT | SUBSTR(source_string, -1, length) |
RPAD | RPAD |
RTRIM | RTRIM |
SOUNDEX | Isn't supported in BigQuery. Consider using a custom UDF |
STRTOK | SPLIT(instring, delimiter)[ORDINAL(tokennum)]
|
SUBSTR/SUBSTRB/SUBSTRC/SUBSTR2/SUBSTR4 | SUBSTR |
TRANSLATE | REPLACE |
TRANSLATE USING | REPLACE |
TRIM | TRIM |
UNISTR | CODE_POINTS_TO_STRING |
UPPER | UPPER |
|| (VERTICAL BARS) | CONCAT |
BigQuery offers the following additional string functions:
BYTE_LENGTH
CODE_POINTS_TO_BYTES
ENDS_WITH
FROM_BASE32
FROM_BASE64
FROM_HEX
NORMALIZE
NORMALIZE_AND_CASEFOLD
REPEAT
SAFE_CONVERT_BYTES_TO_STRING
SPLIT
STARTS_WITH
STRPOS
TO_BASE32
TO_BASE64
TO_CODE_POINTS
The following table shows mappings between Oracle math functions and their BigQuery equivalents.
Oracle | BigQuery |
---|---|
ABS | ABS |
ACOS | ACOS |
ACOSH | ACOSH |
ASIN | ASIN |
ASINH | ASINH |
ATAN | ATAN |
ATAN2 | ATAN2 |
ATANH | ATANH |
CEIL | CEIL |
CEILING | CEILING |
COS | COS |
COSH | COSH |
EXP | EXP |
FLOOR | FLOOR |
GREATEST | GREATEST |
LEAST | LEAST |
LN | LN |
LNNVL | use with ISNULL |
LOG | LOG |
MOD (% operator) | MOD |
POWER (** operator) | POWER, POW |
DBMS_RANDOM.VALUE | RAND |
RANDOMBYTES | Isn't supported in BigQuery. Consider using a custom UDF and RAND function |
RANDOMINTEGER | CAST(FLOOR(10*RAND()) AS INT64) |
RANDOMNUMBER | Isn't supported in BigQuery. Consider using a custom UDF and RAND function |
REMAINDER | MOD |
ROUND | ROUND |
ROUND_TIES_TO_EVEN | ROUND() |
SIGN | SIGN |
SIN | SIN |
SINH | SINH |
SQRT | SQRT |
STANDARD_HASH | FARM_FINGERPRINT, MD5, SHA1, SHA256, SHA512 |
STDDEV | STDDEV |
TAN | TAN |
TANH | TANH |
TRUNC | TRUNC |
NVL | IFNULL(expr, 0), COALESCE(exp, 0) |
BigQuery offers the following additional math functions:
The following table shows mappings between Oracle type conversion functions and their BigQuery equivalents.
Oracle | BigQuery | |
---|---|---|
BIN_TO_NUM | SAFE_CONVERT_BYTES_TO_STRING(value) | |
BINARY2VARCHAR | SAFE_CONVERT_BYTES_TO_STRING(value) | |
CAST | CAST(expr AS typename) | |
CHARTOROWID | Oracle specific not needed. | |
CONVERT | BigQuery doesn't support character sets. Consider using custom user-defined function. | |
EMPTY_BLOB | BLOB is not used in BigQuery. | |
EMPTY_CLOB | CLOB is not used in BigQuery. | |
FROM_TZ | Types with time zones are not supported in BigQuery. Consider using a user-defined function and FORMAT_TIMESTAMP | |
INT_TO_BOOL | CAST | |
IS_BIT_SET | Does not exist implicitly in BigQuery. Consider using UDFs | |
NCHR | UDF can be used to get char equivalent of binary | |
NUMTODSINTERVAL | INTERVAL data type is not supported in BigQuery | |
NUMTOHEX | Isn't supported in BigQuery. Consider using a custom UDF and TO_HEX function | |
NUMTOHEX2 | ||
NUMTOYMINTERVAL | INTERVAL data type is not supported in BigQuery. | |
RAW_TO_CHAR | Oracle specific, does not exist in BigQuery. | |
RAW_TO_NCHAR | Oracle specific, does not exist in BigQuery. | |
RAW_TO_VARCHAR2 | Oracle specific, does not exist in BigQuery. | |
RAWTOHEX | Oracle specific, does not exist in BigQuery. | |
RAWTONHEX | Oracle specific, does not exist in BigQuery. | |
RAWTONUM | Oracle specific, does not exist in BigQuery. | |
RAWTONUM2 | Oracle specific, does not exist in BigQuery. | |
RAWTOREF | Oracle specific, does not exist in BigQuery. | |
REFTOHEX | Oracle specific, does not exist in BigQuery. | |
REFTORAW | Oracle specific, does not exist in BigQuery. | |
ROWIDTOCHAR | ROWID is Oracle specific type and does not exist in BigQuery. This value should be represented as string. | |
ROWIDTONCHAR | ROWID is Oracle specific type and does not exist in BigQuery. This value should be represented as string. | |
SCN_TO_TIMESTAMP | SCN is Oracle specific type and does not exist in BigQuery. This value should be represented as timestamp. | |
TO_ACLID TO_TIMESTAMP TO_TIMESTAMP_TZ TO_TIME_TZ TO_UTC_TIMEZONE_TZ TO_YMINTERVAL | CAST(expr AS typename) PARSE_DATE PARSE_TIMESTAMP Cast syntax is used in a query to indicate that the result type of an expression should be converted to some other type. | |
TREAT | Oracle specific, does not exist in BigQuery. | |
VALIDATE_CONVERSION | Isn't supported in BigQuery. Consider using a custom UDF | |
VSIZE | Isn't supported in BigQuery. Consider using a custom UDF |
The following table shows mappings between Oracle JSON functions and their BigQuery equivalents.
Oracle | BigQuery |
---|---|
AS_JSON | TO_JSON_STRING(value[, pretty_print]) |
JSON_ARRAY | Consider using UDFs and TO_JSON_STRING function |
JSON_ARRAYAGG | Consider using UDFs and TO_JSON_STRING function |
JSON_DATAGUIDE | Custom user-defined function. |
JSON_EQUAL | Custom user-defined function. |
JSON_EXIST | Consider using UDFs and JSON_EXTRACT or JSON_EXTRACT_SCALAR |
JSON_MERGEPATCH | Custom user-defined function. |
JSON_OBJECT | Is not supported by BigQuery. |
JSON_OBJECTAGG | Is not supported by BigQuery. |
JSON_QUERY | Consider using UDFs and JSON_EXTRACT or JSON_EXTRACT_SCALAR . |
JSON_TABLE | Custom user-defined function. |
JSON_TEXTCONTAINS | Consider using UDFs and JSON_EXTRACT or JSON_EXTRACT_SCALAR . |
JSON_VALUE | JSON_EXTRACT_SCALAR |
BigQuery does not provide implicit XML functions. XML can be loaded to BigQuery as string and UDFs can be used to parse XML. Alternatively, XML processing be done by an ETL/ELT tool such as Dataflow. The following list shows Oracle XML functions:
Oracle | BigQuery |
---|---|
DELETEXML | BigQuery UDFs or ETL tool like Dataflow can be used to process XML. |
ENCODE_SQL_XML | |
EXISTSNODE | |
EXTRACTCLOBXML | |
EXTRACTVALUE | |
INSERTCHILDXML | |
INSERTCHILDXMLAFTER | |
INSERTCHILDXMLBEFORE | |
INSERTXMLAFTER | |
INSERTXMLBEFORE | |
SYS_XMLAGG | |
SYS_XMLANALYZE | |
SYS_XMLCONTAINS | |
SYS_XMLCONV | |
SYS_XMLEXNSURI | |
SYS_XMLGEN | |
SYS_XMLI_LOC_ISNODE | |
SYS_XMLI_LOC_ISTEXT | |
SYS_XMLINSTR | |
SYS_XMLLOCATOR_GETSVAL | |
SYS_XMLNODEID | |
SYS_XMLNODEID_GETLOCATOR | |
SYS_XMLNODEID_GETOKEY | |
SYS_XMLNODEID_GETPATHID | |
SYS_XMLNODEID_GETPTRID | |
SYS_XMLNODEID_GETRID | |
SYS_XMLNODEID_GETSVAL | |
SYS_XMLT_2_SC | |
SYS_XMLTRANSLATE | |
SYS_XMLTYPE2SQL | |
UPDATEXML | |
XML2OBJECT | |
XMLCAST | |
XMLCDATA | |
XMLCOLLATVAL | |
XMLCOMMENT | |
XMLCONCAT | |
XMLDIFF | |
XMLELEMENT | |
XMLEXISTS | |
XMLEXISTS2 | |
XMLFOREST | |
XMLISNODE | |
XMLISVALID | |
XMLPARSE | |
XMLPATCH | |
XMLPI | |
XMLQUERY | |
XMLQUERYVAL | |
XMLSERIALIZE | |
XMLTABLE | |
XMLTOJSON | |
XMLTRANSFORM | |
XMLTRANSFORMBLOB | |
XMLTYPE |
Machine learning (ML) functions in Oracle and BigQuery are different. Oracle requires advanced analytics pack and licenses to do ML on the database. Oracle uses the DBMS_DATA_MINING
package for ML. Converting Oracle data miner jobs requires rewriting the code, you can choose from comprehensive Google AI product offerings such as BigQuery ML, AI APIs (including Speech-to-Text, Text-to-Speech , Dialogflow, Cloud Translation, NLP, Cloud Vision, and Timeseries Insights API, AutoML, AutoML Tables or AI Platform. Google user-managed notebooks can be used as a development environment for data scientists and Google AI Platform Training can be used to run training and scoring workloads at scale. The following table shows Oracle ML functions:
Oracle | BigQuery |
---|---|
CLASSIFIER | See BigQuery ML for machine learning classifier and regression options |
CLUSTER_DETAILS | |
CLUSTER_DISTANCE | |
CLUSTER_ID | |
CLUSTER_PROBABILITY | |
CLUSTER_SET | |
PREDICTION | |
PREDICTION_BOUNDS | |
PREDICTION_COST | |
PREDICTION_DETAILS | |
PREDICTION_PROBABILITY | |
PREDICTION_SET |
The following table shows the functions for identifying the user in Oracle and BigQuery:
Oracle | BigQuery |
---|---|
UID | SESSION_USER |
USER/SESSION_USER/CURRENT_USER | SESSION_USER() |
The following table shows set or array functions in Oracle and their equivalents in BigQuery:
Oracle | BigQuery |
---|---|
MULTISET | ARRAY_AGG |
MULTISET EXCEPT | ARRAY_AGG([DISTINCT] expression) |
MULTISET INTERSECT | ARRAY_AGG([DISTINCT]) |
MULTISET UNION | ARRAY_AGG |
The following table shows window functions in Oracle and their equivalents in BigQuery.
Oracle | BigQuery |
---|---|
LAG | LAG (value_expression[, offset [, default_expression]]) |
LEAD | LEAD (value_expression[, offset [, default_expression]]) |
Hierarchical or recursive queries are not used in BigQuery. If the depth of the hierarchy is known similar functionality can be achieved with joins, as illustrated in the following example. Another solution would be to utilize the BigQueryStorage API and Spark.
selectarray(selecte.update.elementunionallselectc1frome.update.element.childasc1unionallselectc2frome.update.element.childasc1,c1.childasc2unionallselectc3frome.update.element.childasc1,c1.childasc2,c2.childasc3unionallselectc4frome.update.element.childasc1,c1.childasc2,c2.childasc3,c3.childasc4unionallselectc5frome.update.element.childasc1,c1.childasc2,c2.childasc3,c3.childasc4,c4.childasc5)asflattened,easeventfromt,t.eventsase
The following table shows hierarchical functions in Oracle.
Oracle | BigQuery |
---|---|
DEPTH | Hierarchical queries are not used in BigQuery. |
PATH | |
SYS_CONNECT_BY_PATH (hierarchical) |
UTL_File
package is mainly used for reading and writing the operating system files from PL/SQL. Cloud Storage can be used for any kind of raw file staging. External tables and BigQuery load and export should be used to read and write files from and to Cloud Storage. For more information, see Introduction to external data sources.
You can use BigQuery geospatial analytics to replace spatial functionality. There are SDO_*
functions and types in Oracle such as SDO_GEOM_KEY
, SDO_GEOM_MBR
, SDO_GEOM_MMB
. These functions are used for spatial analysis. You can use geospatial analytics to do spatial analysis.
This section addresses differences in data management language syntax between Oracle and BigQuery.
INSERT
statementMost Oracle INSERT
statements are compatible with BigQuery. The following table shows exceptions.
DML scripts in BigQuery have slightly different consistency semantics than the equivalent statements in Oracle. For an overview of snapshot isolation and session and transaction handling, see the CREATE [UNIQUE] INDEX section
elsewhere in this document.
Oracle | BigQuery |
---|---|
INSERT INTOtable VALUES (...); | INSERT INTOtable (...) VALUES (...); Oracle offers a Note: In BigQuery, omitting column names in the |
INSERT INTOtable VALUES (1,2,3); | INSERT INTOtable VALUES (1,2,3), (4,5,6), BigQuery imposes DML quotas, which restrict the number of DML statements you can execute daily. To make the best use of your quota, consider the following approaches:
|
UPDATE
statementOracle UPDATE
statements are mostly compatible with BigQuery, however, in BigQuery the UPDATE
statement must have a WHERE
clause.
As a best practice, you should prefer batch DML statements over multiple single UPDATE
and INSERT
statements. DML scripts in BigQuery have slightly different consistency semantics than equivalent statements in Oracle. For an overview on snapshot isolation and session and transaction handling see the CREATE INDEX
section in this document.
The following table shows Oracle UPDATE
statements and BigQuery statements that accomplish the same tasks.
In BigQuery the UPDATE
statement must have a WHERE
clause. For more information about UPDATE
in BigQuery, see the BigQuery UPDATE examples in the DML documentation.
DELETE
and TRUNCATE
statementsThe DELETE
and TRUNCATE
statements are both ways to remove rows from a table without affecting the table schema. TRUNCATE
is not used in BigQuery. However, you can use DELETE
statements to achieve the same effect.
In BigQuery, the DELETE
statement must have a WHERE
clause. For more information about DELETE
in BigQuery, see the BigQuery DELETE
examples in the DML documentation.
Oracle | BigQuery |
---|---|
DELETEdatabase.table; | DELETE FROM table WHERE TRUE; |
MERGE
statementThe MERGE
statement can combine INSERT
, UPDATE
, and DELETE
operations into a single UPSERT
statement and perform the operations atomically. The MERGE
operation must match, at most, one source row for each target row. BigQuery and Oracle both follow ANSI Syntax.
However, DML scripts in BigQuery have slightly different consistency semantics than the equivalent statements in Oracle.
This section addresses differences in data definition language syntax between Oracle and BigQuery.
CREATE TABLE
statementMost Oracle CREATE TABLE
statements are compatible with BigQuery, except for the following constraints and syntax elements, which are not used in BigQuery:
STORAGE
TABLESPACE
DEFAULT
GENERATED ALWAYS AS
ENCRYPT
PRIMARY KEY (col, ...)
. For more information, see CREATE INDEX
.UNIQUE INDEX
. For more information, see CREATE INDEX
.CONSTRAINT..REFERENCES
DEFAULT
PARALLEL
COMPRESS
For more information about CREATE TABLE
in BigQuery, see the BigQuery CREATE TABLE
examples.
Identity columns are introduced with Oracle 12c version which enables auto-increment on a column. This is not used in BigQuery, this can be achieved with the following batch way. For more information about surrogate keys and slowly changing dimensions (SCD), refer to the following guides:
Oracle | BigQuery |
---|---|
CREATE TABLE table ( | INSERT INTO dataset.table SELECT |
Oracle uses Comment
syntax to add comments on columns. This feature can be similarly implemented in BigQuery using the column description as shown in the following table:
Oracle | BigQuery |
---|---|
Comment on column table is 'column desc'; | CREATE TABLEdataset.table ( |
Oracle supports temporary tables, which are often used to store intermediate results in scripts. Temporary tables are supported in BigQuery.
Oracle | BigQuery |
---|---|
CREATE GLOBAL TEMPORARY TABLE | CREATE TEMP TABLE temp_tab |
The following Oracle elements are not used in BigQuery:
ON COMMIT DELETE ROWS;
ON COMMIT PRESERVE ROWS;
There are also some other ways to emulate temporary tables in BigQuery:
temp
to clearly denote that the tables are temporary.Table TTL: Create a table that has a table-specific short time to live using DDL statements similar to the following:
CREATE TABLE temp.name (col1, col2, ...)
OPTIONS(expiration_timestamp=TIMESTAMP_ADD(CURRENT_TIMESTAMP(), INTERVAL 1 HOUR));
WITH
clause: If a temporary table is needed only within the same block, use a temporary result using a WITH
statement or subquery.
CREATE SEQUENCE
statementSequences are not used in BigQuery, this can be achieved with the following batch way. For more information about surrogate keys and slowly changing dimensions (SCD), refer to the following guides:
INSERT INTO dataset.table SELECT *, ROW_NUMBER() OVER () AS id FROM dataset.table
CREATE VIEW
statementThe following table shows equivalents between Oracle and BigQuery for the CREATE VIEW
statement.
Oracle | BigQuery | Notes |
---|---|---|
CREATE VIEWview_name AS SELECT ... | CREATE VIEW view_name AS SELECT ... | |
CREATE OR REPLACE VIEW view_name AS SELECT ... | CREATE OR REPLACE VIEW view_name AS SELECT ... | |
Not supported | CREATE VIEW IF NOT EXISTS view_name OPTIONS(view_option_list) AS SELECT ... | Creates a new view only if the view does not currently exist in the specified dataset. |
CREATE MATERIALIZED VIEW
statementIn BigQuery materialized view refresh operations are done automatically. There is no need to specify refresh options (for example, on commit or on schedule) in BigQuery. For more information, see Introduction to materialized views.
In case the base table keeps changing by appends only, the query that uses materialized view (whether view is explicitly referenced or selected by the query optimizer) scans all materialized view plus a delta in the base table since the last view refresh. This means queries are faster and cheaper.
On the contrary, if there were any updates (DML UPDATE / MERGE) or deletions (DML DELETE, truncation, partition expiration) in the base table since the last view refresh, the materialized view are not be scanned and hence query don't get any savings until the next view refresh. Basically, any update or deletion in the base table invalidates the materialized view state.
Also, the data from the streaming buffer of the base table is not saved into materialized view. Streaming buffer is still being scanned fully regardless of whether materialized view is used.
The following table shows equivalents between Oracle and BigQuery for the CREATE MATERIALIZED VIEW
statement.
Oracle | BigQuery | Notes |
---|---|---|
CREATE MATERIALIZED VIEW view_name | CREATE MATERIALIZED VIEW |
CREATE [UNIQUE] INDEX
statementThis section describes approaches in BigQuery for how to create functionality similar to indexes in Oracle.
BigQuery doesn't need explicit indexes, because it's a column-oriented database with query and storage optimization. BigQuery provides functionality such as partitioning and clustering as well as nested fields, which can increase query efficiency and performance by optimizing how data is stored.
In Oracle, a unique index can be used to prevent rows with non-unique keys in a table. If a process tries to insert or update data that has a value that's already in the index the operation fails with an index violation.
Because BigQuery doesn't provide explicit indexes, a MERGE
statement can be used instead to insert only unique records into a target table from a staging table while discarding duplicate records. However, there is no way to prevent a user with edit permissions from inserting a duplicate record.
To generate an error for duplicate records in BigQuery you can use a MERGE
statement from the staging table, as shown in the following example:
Oracle | BigQuery | |
---|---|---|
CREATE [UNIQUE] INDEX name; | MERGE `prototype.FIN_MERGE` t \ |
More often, users prefer to remove duplicates independently in order to find errors in downstream systems.
BigQuery does not support DEFAULT
and IDENTITY
(sequences) columns.
BigQuery doesn't have a lock mechanism like Oracle and can run concurrent queries (up to your quota). Only DML statements have certain concurrency limits and might require a table lock during execution in some scenarios.
This section describes how to convert procedural SQL statements used in stored procedures, functions and triggers from Oracle to BigQuery.
CREATE PROCEDURE
statementStored Procedure is supported as part of BigQuery Scripting Beta.
Oracle | BigQuery | Notes |
---|---|---|
CREATE PROCEDURE | CREATE PROCEDURE | Similar to Oracle, BigQuery supports IN, OUT, INOUT argument modes. Other syntax specifications are not supported in BigQuery. |
CREATE OR REPLACE PROCEDURE | CREATE OR REPLACE PROCEDURE | |
CALL | CALL |
The sections that follow describe ways to convert existing Oracle procedural statements to BigQuery scripting statements that have similar functionality.
CREATE TRIGGER
statementTriggers are not used in BigQuery. Row based application logic should be handled on the application layer. Trigger functionality can be achieved utilising the ingestion tool, Pub/Sub and/or Cloud Run functions during the ingestion time or utilising regular scans.
The following table shows Oracle DECLARE
statements and their BigQuery equivalents.
Oracle | BigQuery |
---|---|
DECLARE | DECLARE L_VAR int64; |
SET var = value; | SETvar = value; |
BigQuery does not support cursors, so the following statements are not used in BigQuery:
DECLARE cursor_name CURSOR [FOR | WITH] ...
OPEN CUR_VAR FOR sql_str;
OPEN cursor_name [USING var, ...];
FETCH cursor_name INTO var, ...;
CLOSE cursor_name;
The following Oracle Dynamic SQL statement and its BigQuery equivalent:
Oracle | BigQuery |
---|---|
EXECUTE IMMEDIATE sql_str | EXECUTE IMMEDIATE |
The following table shows Oracle flow-of-control statements and their BigQuery equivalents.
Oracle | BigQuery |
---|---|
IF condition THEN | IF condition THEN |
SET SERVEROUTPUT ON; | DECLARE x INT64 DEFAULT 0; |
LOOP | LOOP |
WHILE boolean_expression DO | WHILE boolean_expression DO |
FOR LOOP | FOR LOOP is not used in BigQuery. Use other LOOP statements. |
BREAK | BREAK |
CONTINUE | CONTINUE |
CONTINUE/EXIT WHEN | Use CONTINUE with IF condition. |
GOTO | GOTO statement does not exist in BigQuery. Use IF condition. |
Oracle | BigQuery |
---|---|
GATHER_STATS_JOB | Not used in BigQuery yet. |
LOCK TABLEtable_name IN [SHARE/EXCLUSIVE] MODE NOWAIT; | Not used in BigQuery yet. |
Alter session set isolation_level=serializable; /
| BigQuery always uses Snapshot Isolation. For details, see Consistency guarantees and transaction isolation in this document. |
EXPLAIN PLAN ... | Not used in BigQuery. Similar features are the query plan explanation in the BigQuery web UI and the slot allocation, and in audit logging in Stackdriver. |
SELECT * FROM DBA_[*]; (Oracle DBA_/ALL_/V$ views) | SELECT * FROM mydataset.INFORMATION_SCHEMA.TABLES; For more information, see Introduction to BigQuery INFORMATION_SCHEMA. |
SELECT * FROM GV$SESSION;
| BigQuery does not have the traditional session concept. You can view query jobs in the UI or export stackdriver audit logs to BigQuery and analyze BigQuery logs for analyzing jobs. For more information, see View job details. |
START TRANSACTION;
| Replacing the contents of a table with query output is the equivalent of a transaction. You can do this with either a query or a copy operation. Using a query:
Using a copy:
|
Both Oracle and BigQuery support transactions (sessions) and therefore support statements separated by semicolons that are consistently executed together. For more information, see Multi-statement transactions.
Oracle error codes and BigQuery error codes are different. If your application logic is currently catching the errors, try to eliminate the source of the error, because BigQuery doesn't return the same error codes.
Both Oracle and BigQuery are atomic—that is, ACID-compliant on a per-mutation level across many rows. For example, a MERGE
operation is atomic, even with multiple inserted and updated values.
Oracle provides read committed or serializable transaction isolation levels. Deadlocks are possible. Oracle insert append jobs run independently.
BigQuery also supports transactions. BigQuery helps ensure optimistic concurrency control (first to commit wins) with snapshot isolation, in which a query reads the last committed data before the query starts. This approach guarantees the same level of consistency on a per-row, per-mutation basis and across rows within the same DML statement, yet avoids deadlocks. In the case of multiple UPDATE
statements against the same table, BigQuery switches to pessimistic concurrency control and queues multiple UPDATE
statements, automatically retrying in case of conflicts. INSERT
DML statements and load jobs can run concurrently and independently to append to tables.
Oracle supports rollbacks. As there is no explicit transaction boundary in BigQuery, there is no concept of an explicit rollback in BigQuery. The workarounds are table decorators or using FOR SYSTEM_TIME AS OF
.
Check BigQuery latest quotas and limits. Many quotas for large-volume users can be raised by contacting the Cloud Customer Care. The following table shows a comparison of the Oracle and BigQuery database limits.
Limit | Oracle | BigQuery |
---|---|---|
Tables per database | Unrestricted | Unrestricted |
Columns per table | 1000 | 10,000 |
Maximum row size | Unlimited (Depends on the column type) | 100 MB |
Column and table name length | If v12.2>= 128 Bytes Else 30 Bytes | 16,384 Unicode characters |
Rows per table | Unlimited | Unlimited |
Maximum SQL request length | Unlimited | 1 MB (maximum unresolved GoogleSQL query length) 12 MB (maximum resolved legacy and GoogleSQL query length) Streaming:
|
Maximum request & response size | Unlimited | 10 MB (request) and 10 GB (response), or virtually unlimited if you use pagination or the Cloud Storage API. |
Maximum number of concurrent sessions | Limited by the sessions or processes parameters | 100 concurrent queries (can be raised with slot reservation), 300 concurrent API requests per user. |
Maximum number of concurrent (fast) loads | Limited by the sessions or processes parameters | No concurrency limit; jobs are queued. 100,000 load jobs per project per day. |
Other Oracle Database limits includes data type limits, physical database limits, logical database limits and process and runtime limits.
Except as otherwise noted, the content of this page is licensed under the Creative Commons Attribution 4.0 License, and code samples are licensed under the Apache 2.0 License. For details, see the Google Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.
Last updated 2025-04-17 UTC.