I like to use glue_sql()
for easy creation of MERGE statements, specifically generating the column names in the INSERT/VALUES section. But to do this, I need to be able to prefix a column identifier with a table name identifier, eg "table1"."col1"
.
I don't show the variations I've tried to try and make this work, but I've tried everything I can think of and just can't seem to get it right. Instead I show my use case, and what I'm wanting to get. Do you have any advice? Is this something glue
can currently do? Essentially I feel like I need to iterate in parallel over a table_name
variable and a column_name
variable, doing identifier quoting and placing a period between them as I go.
You can ignore most of the code below and just look at the SQL output at the bottom if you want.
(I was planning on submitting this as an issue to glue
but felt it more appropriate to post here instead unless we determine this is something glue
does not yet support)
library(glue)
library(tibble)
library(DBI)
library(odbc)
# imagine this is already in the db
target_tbl <- cars
# these are the new rows we want to append if they are actually new data
# imagine that I ran a copy_to() on this and named it ##temp_source
source_tbl <- tibble(speed = 25, `dist spaces` = 3)
target_table <- c("target_tbl")
source_table <- c("##temp_source")
# Mock my S4 sql server connection
setClass("Microsoft SQL Server", representation(quote = "character"), contains = "OdbcConnection")
conn <- new("Microsoft SQL Server", quote = "\"")
# really these are colnames(tbl(con, target_table))
target_names <- colnames(target_tbl)
source_names <- colnames(source_tbl)
sql_merge <- glue_sql(
'
MERGE INTO {`target_table`} WITH (HOLDLOCK) AS target
USING {`source_table`} as source
ON target.date = source.date
WHEN NOT MATCHED BY TARGET THEN
INSERT ({`target_names`*})
VALUES ({`source_names`*});
',
.con = conn
)
# This gives me this, which is right, but I need to specify the table
# as well
sql_merge
#> <SQL> MERGE INTO "target_tbl" WITH (HOLDLOCK) AS target
#> USING "##temp_source" as source
#> ON target.date = source.date
#> WHEN NOT MATCHED BY TARGET THEN
#> INSERT ("speed", "dist")
#> VALUES ("speed", "dist spaces");
# I somehow need this:
# <SQL> MERGE INTO "target_tbl" WITH (HOLDLOCK) AS target
# USING "##temp_source" as source
# ON target.date = source.date
# WHEN NOT MATCHED BY TARGET THEN
# INSERT ("speed", "dist")
# VALUES ("source"."speed", "source"."dist spaces");
Created on 2018-07-27 by the reprex package (v0.2.0).