Domanda

Ho sviluppato un sondaggio online che memorizza i miei dati in un database Microsoft SQL 2005. Ho scritto una serie di controlli di valori anomali sui miei dati in R. Il flusso di lavoro generale per questi script è:

  1. leggere i dati dal database SQL con sqlquery ()
  2. Eseguire outlier analisi
  3. Scrivi offendere intervistati Torna alla banca dati in tabella separata utilizzando sqlSave ()

La tabella che sto scrivendo di nuovo a ha la struttura:

CREATE TABLE outliers2(
    modelid int
    , password varchar(50)
    , reason varchar(50),
Constraint PK_outliers2 PRIMARY KEY(modelid, reason)
)
GO

Come potete vedere, ho impostato la chiave primaria per essere modelid e la ragione. Lo stesso convenuto può essere un outlier per più controlli, ma non voglio inserire la stessa modelid e la ragione combo per ogni rispondente.

Dal momento che stiamo ancora raccogliendo i dati, mi piacerebbe essere in grado di aggiornare questi script su base giornaliera / settimanale, come ho sviluppato dei modelli che sto stima sui dati. Ecco la forma generale del comando sqlSave() sto usando:

sqlSave(db, db.insert, "outliers2", append = TRUE, fast = FALSE, rownames = FALSE)

dove db è una connessione ODBC valida e db.insert ha la forma

> head(db.insert)
  modelid password          reason
1     873       abkd WRONG DIRECTION
2     875       ab9d WRONG DIRECTION
3     890       akdw WRONG DIRECTION
4     905       pqjd WRONG DIRECTION
5     941       ymne WRONG DIRECTION
6     944       okyt WRONG DIRECTION

induttanze sqlSave() quando tenta di inserire una riga che viola il vincolo di chiave primaria e non continuare con gli altri record per l'inserto. Avrei pensato che l'impostazione fast = FALSE avrebbe alleviato questo problema, ma non è così.

Tutte le idee su come risolvere questo problema? Potrei sempre drop la tabella all'inizio del primo script, ma che sembra abbastanza mano pesante e senza dubbio portare a problemi lungo la strada.

È stato utile?

Soluzione

In questo caso, tutto funziona come previsto. È il caricamento di tutto come un batch e SQL Server è fermare il batch non appena trova un errore. Purtroppo, non so di una graziosa built-in soluzione. Ma, penso che sia possibile costruire un sistema nel database per gestire in modo più efficiente. Mi piace fare la memorizzazione dei dati / gestione in banche dati, piuttosto che all'interno di R, quindi la mia soluzione è molto pesante database. Altri possono offrire una soluzione che è più orientato R.

In primo luogo, creare una tabella semplice, senza vincoli, per tenere i vostri nuove righe e regolare la sua dichiarazione sqlSave conseguenza. Questo è dove R sarà caricare le informazioni a.

CREATE TABLE tblTemp(
    modelid int
    , password varchar(50)
    , reason varchar(50)
    , duplicate int()
)
GO

I dati di informazioni messo in questa tabella dovrebbe assumere 'No' per la colonna 'duplicato'. Io uso un modello dove 1 = Y = N 5. Si potrebbe anche marcare solo quelli che sono i valori anomali, ma io tendo a preferire di essere esplicito con la mia logica.

Si avrà anche bisogno di un posto per scaricare tutte le righe che violano la PK in outliers2.

CREATE TABLE tblDuplicates(
    modelid int
    , password varchar(50)
    , reason varchar(50)
)
GO

OK. Ora tutto quello che dovete fare è creare un trigger per spostare le nuove righe da tblTemp a outliers2. Questo trigger sposterà tutte le righe duplicate per tblDuplicates per la gestione successiva, la cancellazione, qualunque sia.

CREATE TRIGGER FindDups
ON tblOutliersTemp
AFTER INSERT
AS 

Non ho intenzione di passare attraverso e scrivere l'intero grilletto. Non ho uno SQL Server 2005 per testare contro e io probabilmente fare un errore di sintassi e io non voglio dare il codice cattivo, ma ecco quali sono le esigenze di trigger da fare:

  1. Identificare tutte le righe in tblTemp che violerebbero la PK in outliers2. Dove si trovano i duplicati, cambiare i duplicati a 1. Questo sarebbe stato fatto con un'istruzione UPDATE.
  2. Copia tutte le righe in cui duplicato = 1 a tblDuplicates. Si potrebbe fare questo con un INSERT INTO tblDuplicates ......
  3. Ora copiare le righe non duplicati a outliers2 con un'istruzione INSERT INTO che sembra quasi esattamente come quello utilizzato nel passaggio 2.
  4. Caduta di tutte le righe da tblTemp, per cancellare fuori per la vostra prossima partita di aggiornamenti. Questo passaggio è importante.

La parte bella di fare in questo modo è sqlSave () non sarà errore fuori solo perché si ha una violazione del PK e si può fare con le partite in un secondo momento, come domani. : -)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top