How to append table in SQL using R? - sql

I am now using odbc/dbplyr R packages to control database. Though I know I could use the function union to bind two tables by row, I don't know how to append one table to another without loading the data into the local memory. Is there any solutions?
Thanks.

I approach this using a combination of dbplyr and DBI packages.
The idea is to insert a table query into an insert statement. The insert statement can then be executed on the database:
append_database_table <- function(db_connection, db, schema, tbl_name, table_to_append) {
query <- glue::glue("INSERT INTO {db}.{schema}.{tbl_name}\n{dbplyr::sql_render(table_to_append)}")
# execute
DBI::dbExecute(db_connection, as.character(query))
}
Notes:
This all assumes that the table you wish to append to already exists in the database. Different syntax is needed if you are creating a new table.
dbplyr::sql_render returns the query that defines the input table
query is a text string of valid database code
I am using SQL Server syntax. You may need to adjust this if you are using a different flavor of SQL.
The above is a minimal example, the full function I use for this contains additional checks and ensures column names are correct. You can find it here along with the other support functions I use for dbplyr work.
This approach works even if your input table has some processing. Consider the following example:
prepared_table = remote_table %>%
filter(!is.na(col1)) %>%
group_by(col1) %>%
summarise(col2sum = sum(col2))
show_query(prepared_table)
This will return SQL code equivalent to:
SELECT col1, SUM(col2) AS col2sum
FROM remote_table
WHERE col1 IS NOT NULL
Appending this using:
append_database_table(db_connection, "db", "my_schema", "existing_table", prepared_table)
Will create the following SQL query and execute it on the database:
INSERT INTO db.my_schema.existing_table
SELECT col1, SUM(col2) AS col2sum
FROM remote_table
WHERE col1 IS NOT NULL

Related

Create SQLite view as a union with source table name field [duplicate]

I want to write a query that examines all the tables in an SQLite database for a piece of information in order to simplify my post-incident diagnostics (performance doesn't matter).
I was hoping to write a query that uses the sqlite_master table to get a list of tables and then query them, all in one query:
SELECT Name
FROM sqlite_master
WHERE Type = 'table' AND (
SELECT count(*)
FROM Name
WHERE conditions
) > 0;
However when attempting to execute this style of query, I receive an error no such table: Name. Is there an alternate syntax that allows this, or is it simply not supported?
SQLite is designed as an embedded database, i.e., to be used together with a 'real' programming language.
To be able to use such dynamic constructs, you must go outside of SQLite itself:
cursor.execute("SELECT name FROM sqlite_master")
rows = cursor.fetchall()
for row in rows:
sql = "SELECT ... FROM {} WHERE ...".format(row[0])
cursor.execute(sql)

SQL Where clause from a file on Oracle

I have a requirement to construct an SQL that has a where clause which is expected to look into a file entries to be used in that clause.
SELECT DISTINCT '/',t_05.puid, ',', t_01.puid,'/', t_01.poriginal_file_name
FROM PWORKSPACEOBJECT t_02, PREF_LIST_0 t_03, PPOM_APPLICATION_OBJECT t_04, PDATASET t_05, PIMANFILE t_01
WHERE t_03.pvalu_0 = t_01.puid AND t_02.puid = t_03.puid AND t_03.puid = t_04.puid AND t_04.puid = t_05.puid AND t_02.puid IN ( 'izeVNXjf44e$yB',
'gWYRvN9044e$yB' );
The above is the SQL query. As you can see the IN clause has two different strings ( puids ) that are to be considered. But in my case, this list is like 50k entries long and would come from splunk and will be in a text file.
Sample output of the text file looks as belows:
'gWYRvN9044e$yB',
'DOZVpdOQ44e$yB',
'TlfVpdOQ44e$yB',
'wOWRehUc44e$yB',
'wyeRehUc44e$yB',
'w6URehUc44e$yB',
'wScRehUc44e$yB',
'yzXVNXjf44e$yB',
'guWRvN9044e$yB',
'QiYRehUc44e$yB',
'gycRvN9044e$yB'
I am not an SQL guru, but a quick google on this gave me a reference to OPENROWSET construct, which is not available on Oracle.
Can you please suggest some pointers on what can be done to circumvent the problem.
Thanks,
Pavan.
Consider using an external table, SQL Loader or perhaps loading the file into a table in the application layer and querying it normally.
I would recommend creating a Global Temporary table, adding the rows to that table, and then joining to your temp table.
How to create a temporary table in Oracle
Other options:
You could also use pipelined functions:
https://oracle-base.com/articles/misc/pipelined-table-functions
Or use the with as... construct to fold the data into the SQL. But that would create a long SQL statement.

How can I use a SQL Server table in an openquery to an Oracle database?

I have a database on SQL Server and would like to use a column in one of my tables in a linked server openquery I'm running to an Oracle database in order to match values between the two and insert the result into columns in my table in SQL Server .
Essentially I want it to be like this:
SELECT col1, col2, col3, col4
FROM OPENQUERY(link, 'SELECT * FROM Oracle_Table
WHERE ID = MSSQL.dbo.table.ID`)
So I'd like to be able to use my internal table column values to query an external database. They are related tables but different systems.
Would it be possible to get a big list of the values in the SQL Server table column and use it as a variable in the Oracle query? I've searched extensively online but haven't been able to find this one.
You can't pass parameters like I wanted to, but I ended up creating a bunch of queries in Powershell using a for loop and variables within the string to create my large query, then put a UNION ALL after each SELECT FROM OPENQUERY()

Is it possible to use a returned column value as a table name in an SQLite query?

I want to write a query that examines all the tables in an SQLite database for a piece of information in order to simplify my post-incident diagnostics (performance doesn't matter).
I was hoping to write a query that uses the sqlite_master table to get a list of tables and then query them, all in one query:
SELECT Name
FROM sqlite_master
WHERE Type = 'table' AND (
SELECT count(*)
FROM Name
WHERE conditions
) > 0;
However when attempting to execute this style of query, I receive an error no such table: Name. Is there an alternate syntax that allows this, or is it simply not supported?
SQLite is designed as an embedded database, i.e., to be used together with a 'real' programming language.
To be able to use such dynamic constructs, you must go outside of SQLite itself:
cursor.execute("SELECT name FROM sqlite_master")
rows = cursor.fetchall()
for row in rows:
sql = "SELECT ... FROM {} WHERE ...".format(row[0])
cursor.execute(sql)

Oracle, dynamically determine column name

Suppose I have a table of custom column names that all have the pattern COL##, where ## is any integer. So a typical query would be:
select COL12 from MyCustomTable;
So in another table, I have all those integers and I'd like to create a query using the table of integers to construct a dynamic query into MyCustomTable.
Something like:
select 'COL' || (select colId from IdTable where Id = 12) from MyCustomTable;
But instead of just returning the string 'COL12' for every row, return the actual values identified by the column name COL12.
Don't worry about my overall problem :) I'm just curious to know if I can do this from a sqldeveloper window directly without writing any code/procedures/functions, etc.
An obvious and absolutely insecure way of doing this would be usage of EXECUTE IMMEDIATE statement.
Another is to use SPOOL command to output results into temporary file, then set SPOOL OFF and execute this file with # directive.