Skip to content

Instantly share code, notes, and snippets.

@javieroot
Last active June 14, 2018 22:35
Show Gist options
  • Save javieroot/9d538457bd10b8c8a9ba52a23947e77d to your computer and use it in GitHub Desktop.
Save javieroot/9d538457bd10b8c8a9ba52a23947e77d to your computer and use it in GitHub Desktop.
Actualiza tablas de Oracle con campos muy grandes, del tipo de dato clob
updateClob <- function(bd, tabla, condiciones = list(), actualizacion = list()){
# Esta función no se recomienda utilizarla cuando el número de registros a
# actualizar es considerablemente grande, ya que descarga la información,
# la actualiza en R, la borra en Oracle y luego la vuelve a subir.
#
# La parte principal de esta función es:
# attr(datosOriginales$', names(conteoCaracteres), ', "ora.type") <- "clob"'
# que solo está disponible en la función dbWriteTable
#
# Las condiciones deben introducirse de esta forma:
# condiciones <- list(var1 = "in('4', '2', '9', '7')",
# var2 = 22222,
# var3 = "in (33333, 23)",
# var4 = 54,
# var5 = "between 30 and 50")
#
# La actualización debe ir de forma similar a las condiciones
# Si no hay condiciones tener cuidado ya que se borra la tabla completa
if(length(actualizacion) == 0){
stop("No se realizó actualización debido a que no se introdujeron datos.")
}
# Descarga de datos -------------------------------------------------------
if(length(condiciones)== 0){
query <- paste("select *
from", tabla)
} else {
# Generación de condiciones -----------------------------------------------
condiciones <- Map(function(lista, nombre) {
lista <- paste(nombre, lista, sep = " = ")
}, condiciones, names(condiciones)
)
# Agrega los and por cada condición
condiciones <- paste(unlist(condiciones), collapse = " and ")
# Quita los = donde encuentra in
condiciones <- gsub("\\s+", " ", trimws(condiciones))
condiciones <- gsub("\\s?=\\s?in\\s?\\(\\s?", " in (", condiciones, ignore.case = T)
# Cambia los = por between donde encuentra between y encierra la condicion entre paréntesis
condiciones <- gsub("\\s?=\\s?between\\s?", " between ", condiciones, ignore.case = T)
condiciones <- gsub("(\\w+\\sbetween\\s\\w+\\sand\\s\\w+)", "(\\1)", condiciones, ignore.case = T)
query <- paste("select *
from", tabla,
"where", condiciones)
}
datosOriginales <- dbGetQuery(bd, query)
# Actualización de datos descargados --------------------------------------
if(nrow(datosOriginales) < 1){
stop("No existen datos a actualizar con las condiciones dadas.")
}
eval(parse(text = paste0("datosOriginales$", names(actualizacion), " <- ", actualizacion)))
# datosOriginales[is.na(datosOriginales)] <- ""
conteoCaracteres <- sapply(datosOriginales, function(x) max(nchar(x, keepNA = FALSE), na.rm = TRUE))
conteoCaracteres <- conteoCaracteres[conteoCaracteres > 4000]
if(length(conteoCaracteres) > 0){
eval(parse(text = paste0('attr(datosOriginales$', names(conteoCaracteres), ', "ora.type") <- "clob"')))
}
# Borrado de datos la tabla de Oracle ------------------------------------
if(length(condiciones) == 0){
query <- paste("delete
from", tabla)
} else {
query <- paste("delete
from", tabla,
"where", condiciones)
}
dbSendQuery(bd, query)
dbCommit(bd)
# Escritura de datos en la tabla de Oracle --------------------------------
# tryCatch({
dbWriteTable(bd, tabla, datosOriginales, append = T)
# }, error = function(err) {
#
# dbRollback(bd)
# print("No se pudo acutalizar la base de datos:")
# stop(err)
#
# })
message("La tabla ", tabla, " se actualizó correctamente.")
return(TRUE)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment