BigQuery does not allow you to rename a table name or a column name. The only option is to take a copy of the table and specify the new table name in BigQuery. This doesn't incur any additional charges other than the additional cost of storage
CREATE OR REPLACE TABLE MYDATASET.MYTABLE_NEW AS
SELECT * FROM MYDATASET.MYTABLE;
DROP TABLE MYDATASET.MYTABLE;
Can I do something similar for Stored procedures via BigQuery Standard SQL? I didn't find anything in the documentation regarding this.
You can try this workaround solution:
[1]:
CREATE OR REPLACE PROCEDURE mydataset.add(INOUT x INT64, y INT64)
BEGIN
SET x = x + y;
END;
[2]:
CREATE OR REPLACE PROCEDURE mydataset.add_new(INOUT x INT64, y INT64)
BEGIN
call mydataset.add(x, y);
END;
Related
I'm writing a simple stored procedure for my Hana database, its behavior is to update a table and return the updated element. Here the code:
CREATE OR REPLACE PROCEDURE "UpdateTbl" (in _id integer, in formula text) AS
BEGIN
UPDATE "MyTable" SET "formula" = formula, WHERE "id" = _id;
SELECT "id", "formula" FROM "MyTable" WHERE "id" = _id;
END;
The problem i'm facing is that I cannot specify a TEXT input parameter in stored procedures.
A possible workaround could be to use NVARCHAR instead.
In this way, I can correctly create the stored procedure, but when I run it with 'dummy' value in the NVARCHAR field, i got this error
Error: (dberror) [7]: feature not supported: "Database"."UpdateTbl": ... : Unregistered function name: "to_text
It seems that it cannot convert NVARCHAR in TEXT.
So, there is a way to force the conversion of this kind of parameter in TEXT?
If not, there is a way I'm not considering to pass TEXT parameter as input (other data types, for instance)?
Thnaks in advance
this simple example works as expected when using NVARCHAR or NCLOB as procedure parameter type
DROP TABLE t1;
CREATE TABLE t1 (i int, t text fast preprocess off);
INSERT INTO t1 values(3,'');
INSERT INTO t1 values(4,'');
CREATE OR REPLACE PROCEDURE p1 (in i int, in t nclob) AS
BEGIN
UPDATE t1 SET t = :t WHERE i = :i;
--SELECT i,t FROM t1 where i = :i;
END;
CALL p1(3,'bob went to london');
CALL p1(4,'nancy moved to berlin');
SELECT * FROM t1 WHERE CONTAINS(*,'go',linguistic);
please provide your column properties
I have to copy data from one table to another with below two conditions
table names will be known at run time
records need to be copied one at a time so that modifications can be done in column values when required
I have created a procedure to to do this through dynamic query. Since the column list is not known already I am not able to declare a rowtype variable. I saw an example of DBMS_SQL where you can define the columns for select clause. Below is the format
DBMS_SQL.DEFINE_COLUMN(cursor_var,position,column_var);
Problem here is that in all the examples I found the column_var were already declared. However in my case I will get to know the no of columns that will be in cursor sql and their data type at run time. so I need to find a way to pass the data type of "column_var" as part of DBMS_SQL.DEFINE_COLUMN. Is there a way to do that? Is there a better way?
Below is just a sample code
CREATE OR REPLACE PROCEDURE pr_test (P_TABLE_NAME IN VARCHAR2)
IS
V_SQL VARCHAR2(500);
SRC_CUR INT;
DEST_CUR INT;
TYPE COL_DTL_TYPE IS RECORD
(
COLUMN_ID INT,
COLUMN_NAME VARCHAR2(250),
DATA_TYPE VARCHAR2(250),
DATA_LENGTH INT
);
COL_DTL_REC COL_DTL_TYPE;
TYPE TBL_COL_LIST_TYPE IS TABLE OF COL_DTL_TYPE;
TBL_COL_LIST TBL_COL_LIST_TYPE;
V_CNT INT := 0;
BEGIN
V_SQL := 'SELECT * FROM ' || P_TABLE_NAME;
SRC_CUR := DBMS_SQL.OPEN_CURSOR;
DBMS_SQL.PARSE(SRC_CUR,V_SQL,DBMS_SQL.NATIVE);
TBL_COL_LIST := TBL_COL_LIST_TYPE();
FOR COL_DTL_REC IN (
SELECT COLUMN_ID,COLUMN_NAME,DATA_TYPE,DATA_LENGTH
FROM ALL_TAB_COLUMNS WHERE TABLE_NAME =P_TABLE_NAME
)
LOOP
V_CNT := V_CNT + 1;
TBL_COL_LIST.EXTEND;
TBL_COL_LIST(V_CNT) := COL_DTL_REC;
-- Here is where I am stuck and not able to give column data type
DBMS_SQL.DEFINE_COLUMN(SRC_CUR,V_CNT,COL_DTL_REC.COLUMN_NAME COL_DTL_REC.DATA_TYPE , COL_DTL_REC.DATA_LENGTH)
END LOOP;
END;
copying to destination table will come later.
I'm migrating some procedures from PostgreSQL to a new DB2 environment. I've got most of it done but I can't find a way to DECLARE a variable for an internal rowset/record.
Basically what the procedure does on Postgres is this:
DECLARE
counts RECORD;
BEGIN
-- fill "counts" with one row of aggregated data
SELECT
COUNT(....) AS failed_inserts,
COUNT(....) AS failed_updates,
COUNT(....) AS failed_deletes,
INTO counts
FROM (...)
-- check "counts" with some conditionals
IF counts.failed_inserts > 0
(...)
END IF;
(...)
-- return info depending on the data
RETURN (...);
END
I can't find an equivalent to declaring "counts" in the IBM manuals or elsewhere online. The row I need is static (3 columns of aggregated data). So it would be enough to declare that row hardcoded if that is possible.
Is it possible to DECLARE a record / dataset / "virtual table" within a Stored Procedure on the DB2?
We're using DB2 for Linux (V10.5) not DB2 for iSeries.
#mustaccio's answer points to the correct solution:
Outside of the procedure create the needed rowtype:
CREATE TYPE empRow AS ROW (failed_inserts INTEGER, failed_updates INTEGER, failed_deletes INTEGER);
Then you can DECLARE the new type within the procedure
DECLARE newRow empRow;
Not sure I fully understand what you want, but may be you're looking for the ROW data type? Something like this:
DECLARE
TYPE counts_row AS ROW (
failed_inserts INT,
failed_updates INT,
failed_deletes INT
);
counts counts_row;
BEGIN
-- fill "counts" with one row of aggregated data
SELECT
COUNT(....) AS failed_inserts,
COUNT(....) AS failed_updates,
COUNT(....) AS failed_deletes,
INTO counts
FROM (...);
...
PS. Not tested.
More info in the manual.
In lieu of creating a permanent** user defined type that is more or less specific to a single query, you can also achieve the same by using the FOR statement:
FOR counts AS c1 CURSOR FOR SELECT COUNT(.....) AS failed_inserts,
COUNT(....) AS failed_updates,
COUNT(....) AS failed_deletes,
FROM (...)
DO
IF counts.failed_inserts > 0 THEN
(....)
END IF;
END FOR;
** Permanent meaning something that's defined in the system catalog.
I am creating a procedure that can explore an analytic view given one dimension, one measure and a filter (where clause)
drop procedure dynamicExploration;
create procedure dynamicExploration(in currentMeasure double, in filter_string
varchar(100), out dataSubset dataExplorationOutputType)
language sqlscript as
begin
dataSplitby = select CITY as ID, SUM(:currentMeasure) as SUM_MEASURE from
_SYS_BIC."package/analyticView" Group by CITY;
--dataSubset = APPLY_FILTER(:dataSplitby, :filter_string);
dataSubset = select * from :dataSplitBy;
end;
where dataSubset is a data type defined as follows:
drop type dataExplorationOutputType;
create type dataExplorationOutputType as table("ID" varchar(100), "SUM_MEASURE" double);
but I am getting this error, could your please check what's wrong;
Could not execute 'create procedure dynamicExploration(in currentMeasure double, in
filter_string varchar(100), out ...' in 166 ms 8 µs .
SAP DBTech JDBC: [266] (at 200): inconsistent datatype: only numeric type is available
for aggregation function: line 4 col 36 (at pos 200)
I also tried to define currentMeasure as varchar but still getting the same error.
What I am trying to achieve eventually is to create a stored procedure that can help another procedure to select a data subset based on a set of given parameters defined by the user: dimension, measure and filters.
drop procedure dynamicExploration;
create procedure dynamicExploration(in currentDimension varchar(100), in currentMeasure double, in filter_string
varchar(100), out dataSubset dataExplorationOutputType)
language sqlscript as
begin
dataSplitby = select :currentDimension as ID, SUM(:currentMeasure) as SUM_MEASURE from
_SYS_BIC."package/analyticView" Group by :currentDimension;
dataSubset = APPLY_FILTER(:dataSplitby, :filter_string);
--dataSubset = select * from :dataSplitBy;
end;
I have already created a procedure to do this kind of dynamic exploration based on dynamic SQL, a feature that is not recommended. What I am looking for is a better solution/idea to do this kind of dynamic exploration of an analytic view (data cube).
thanks
You will have to construct a dynamic SQL and execute it with the EXECUTE IMMEDIATE command. I know it's not recommended, but your use case requires it. Make sure to protect yourself from SQL injection, e.g. by checking the name of the dimension that is passed into your wrapper procedure against a list of "allowed" dimensions
I'm using a TDataSet where the CommandText property is set to an SQL query. I have also made the following function which creates part of an SQL query based on the fields of TDataSet. It is however incomplete. As you can see I still need to get the name of the table that a TField is from. How do I achieve this?
function GetDataSetFieldsMSSQL(Dataset: TDataSet): String;
var
I, L: Integer;
TableName: String;
begin
Result := '';
L := Dataset.Fields.Count;
if (L > 0) then
begin
TableName := ... // Name of the table for the Dataset.Fields[0] field.
Result := '[' + TableName + '].[' + Dataset.Fields[0].FieldName + ']';
I := 1;
while (I < L) do
begin
TableName := ... // Name of the table for the Dataset.Fields[I] field.
Result := Result + ',[' + TableName + '].[' + Dataset.Fields[I].FieldName + ']';
Inc(I);
end;
end;
end;
You can use the Delphi Function GetTableNameFromQuery(SQL : String):String; from the DBCommon unit. Just Add The DBCommon on the uses. =)
Maybe there is no solution at all for a simple TDataSet?
I believe not. Because an TDataset can source its' data not only from RDBMS' tables.
It can be:
an RSS feed
An XML file. Example: TCliendataset is an TDataset descendant that can read XML from its'
own format or using an XMLTransformProvider.
It can be an SQL for reading an Excel spreadsheet or a text file if you have an ODBC driver for
that and configured the datasource.
Sky (and the imagination of Delphi's programmers around the world) is the limit for what a field can represent in an TDataset.
You have some alternatives, since you are using an ADODataset:
Parsing the commandText of ADOCommand
Using the BASETABLENAME property of ADORecordSet (as in kobik's comment)
Guessing by convention ( Abelisto's answer )
As I know there is no any way to get the name of the table from the SQL query component.
However you can give aliases for fields, for example: "select foo_field as foo_dot_foo_field from foo" and then replace them to the correct syntax: "Result := '[' + StringReplace(DataSet.Fields[0].FieldName, 'dot', '].[', [rfReplaceAll]) + ']'"
What you are trying to do is impossible if you have no knowledge or control over the SQL used in the query.
The query could contain calculated/computed fields or could be returning fields from a view etc. Furthermore the database might have several tables that contain the same field names.
If possible you can query the SQL server view INFORMATION_SCHEMA.COLUMNS and that way try to figure out what table a fieldname is from. However if the field names are not unique this might also prove impossible.