2012-08-14 20 views
9

मेरे डेटाबेस तालिका इस तरह लगभग दिखता है:RODBC: SQLUpdate() को नहीं पहचानता सूचकांक स्तंभ

+-----+-------+--------------------+-----------+----------+ 
| ID1 | ID2 | FilePath1   | FilePath2 | Status | 
+-----+-------+--------------------+-----------+----------+ 
| 1 | Test1 | MyFolder\R\Folder1 | NULL  | Open  | 
| 2 | Test2 | MyFolder\R\Folder2 | NULL  | Open  | 
| 3 | Test3 | MyFolder\R\Folder3 | NULL  | Finished | 
| 4 | Test4 | MyFolder\R\Folder4 | NULL  | Finished | 
+-----+-------+--------------------+-----------+----------+ 

पहले कॉलम (ID1) पी के रूप में परिभाषित किया गया है। हालांकि, आईडी 2 भी अद्वितीय है।

अब मैं आर RODBC पैकेज से sqlUpdate() उपयोग करने के साथ FilePath2 और Status को बदलने में सक्षम होना चाहते हैं। तो मैं निम्न प्रयास करें:

db.df <- data.frame(ID1=1, ID2='Test1', 
        FilePath2='MyFolder\R\Folder5', Status='Finished', 
        stringsAsFactors=FALSE) 

sqlUpdate(myconn, db.df, tablename='mytable', index='ID2', verbose=TRUE) 

जिसमें db.df है डेटाबेस तालिका (हालांकि, मैं इस मामले FilePath1 में स्तंभों में से कुछ बाहर छोड़ देते हैं, और मैं के भीतर उन के लिए इसी एक पंक्ति और स्तंभ नाम के साथ एक डेटा फ्रेम ID1 को भी छोड़ना पसंद करते हैं, यदि संभव हो तो भी)।

+-----+-------+--------------------+--------------------+----------+ 
| ID1 | ID2 | FilePath1   | FilePath2   | Status | 
+-----+-------+--------------------+--------------------+----------+ 
| 1 | Test1 | MyFolder\R\Folder1 | MyFolder\R\Folder5 | Finished | 
| 2 | Test2 | MyFolder\R\Folder2 | NULL    | Open  | 
| 3 | Test3 | MyFolder\R\Folder3 | NULL    | Finished | 
| 4 | Test4 | MyFolder\R\Folder4 | NULL    | Finished | 
+-----+-------+--------------------+--------------------+----------+ 

मैं folllowing त्रुटि मिलती है:

Error in sqlUpdate(myconn, db.df, tablename = 'mytable', index = 'ID2', : 
index column(s) ID2 not in database table 

क्या इस समस्या का कारण हो सकता है मेरा उद्देश्य निम्नलिखित प्राप्त करने के लिए है?


संपादित करें: मैं एक सीधा एसक्यूएल क्वेरी भेजकर समस्या को नजरअंदाज कर दिया है:

out.path <- 'MyFolder\\\\R\\\\Folder5' 
update.query <- paste("UPDATE mytable ", 
        "SET FilePath2='", out.path, "', Status='Finished' ", 
        "WHERE ID2='Test1'", sep="") 
dummy <- sqlQuery(myconn, update.query) 

यद्यपि यह एक साफ रास्ता नहीं हो सकता है, यह इसके क्या करना चाहिए है। हालांकि, मुझे अभी भी समझ में नहीं आता कि sqlUpdate के साथ क्या मामला है, इसलिए मुझे उम्मीद है कि कोई इस पर प्रकाश डाल सकता है।

उत्तर

0

sqlUpdate मेरे लिए काम किया। केवल एक चीज जिसे मैं बदलना था db.df था - \ वर्ण को दोगुना करने की आवश्यकता है ताकि वह इसके साथ कोड से बचने की कोशिश न करे। मेरी टेस्ट टेबल इस तरह दिखती है:

CREATE TABLE mytable (
    ID1 INT NOT NULL PRIMARY KEY, 
    ID2 VARCHAR(10) NOT NULL, 
    FilePath1 VARCHAR(50) NOT NULL, 
    FilePath2 VARCHAR(50) NULL, 
    Status VARCHAR(15) NOT NULL) 

insert into mytable values(1,'Test1','MyFolder\R\Folder1',NULL,'Open') 
insert into mytable values(2,'Test2','MyFolder\R\Folder2',NULL,'Open') 
insert into mytable values(3,'Test3','MyFolder\R\Folder3',NULL,'Finished') 
insert into mytable values(4,'Test4','MyFolder\R\Folder4',NULL,'Finished') 

मैं अद्यतन में ID1 या FilePath1 फ़ील्ड्स के बिना अद्यतन चलाने में सक्षम था। यदि आप प्रलेखन (? SqlUpdate) पढ़ते हैं तो यह कहता है: 'सबसे पहले यह तालिका के लिए प्राथमिक कुंजी की तलाश करता है, फिर कॉलम (ओं) के लिए जो डेटाबेस विशिष्ट रूप से' पंक्ति को परिभाषित करने के लिए इष्टतम मानता है, तो आप डॉन करते हैं प्राथमिक कुंजी का उपयोग नहीं करना है, हालांकि अगर आपको पता नहीं था कि आईडी 2 अद्वितीय था तो प्राथमिक कुंजी का उपयोग करना सबसे अच्छा होगा।

db.df <- data.frame(ID2='Test1', FilePath2='MyFolder\\R\\Folder5', Status='Finished',     stringsAsFactors=FALSE) 
sqlUpdate(myconn, db.df, tablename='mytable', index='ID2', verbose=TRUE) 
1

मैं जब sqlUpdate का उपयोग कर MySQL में एक मेज अद्यतन करने के लिए एक ऐसी ही समस्या आ रही। मैंने R-MySQL कनेक्शन में case विशेषताओं को सेट करके इसे ठीक किया।

myDF <- data.frame(myName1 = 111, myName2 = 'Test3') 
sqlUpdate(myConn, myDF, tablename='myTable', index = 'myName1', verbose=TRUE) 

#> Error in sqlUpdate(myConn, myDF, tablename='myTable', index = 'myName1', verbose=TRUE) : 
    index column(s) myName1 not in data frame 

कारण है कि (डिफ़ॉल्ट:

MySQL में:

create table myTable (
myName1 INT NOT NULL PRIMARY KEY, 
myName2 VARCHAR(10) NOT NULL, 
); 

insert into myTable values(111, 'Test1') 
insert into myTable values(222, 'Test2') 

आर में

यहाँ विस्तार है?) RMySQL संबंध में जिम्मेदार बताते हैं:

> attr(myConn, "case") 
[1] "tolower" 

तो, myDF में colname myName1 मामले myname1 को sqlUpdate अंदर बदल दिया गया है, तो यह myName1 दिए गए इंडेक्स को मेल नहीं खाता।

ध्यान दें कि अगर कोई index = 'myname1' के साथ कॉल बदलता है तो यह काम नहीं करेगा। index column(s) myName1 not in database table की एक त्रुटि की सूचना दी जाएगी। क्योंकि MySQL तालिका में, colname myName है।

debugonce(sqlUpdate) देता है::

cnames <- colnames(dat) 
    cnames <- mangleColNames(cnames) 
    cnames <- switch(attr(channel, "case"), nochange = cnames, 
     toupper = toupper(cnames), tolower = tolower(cnames)) 
    cdata <- sqlColumns(channel, tablename) 
    coldata <- cdata[c(4L, 5L, 7L, 9L)] 
    if (is.character(index)) { 
     intable <- index %in% coldata[, 1L] 
     if (any(!intable)) 
      stop("index column(s) ", paste(index[!intable], collapse = " "), 
       " not in database table") 
     intable <- index %in% cnames 
     if (any(!intable)) 
      stop("index column(s) ", paste(index[!intable], collapse = " "), 
       " not in data frame") 
     indexcols <- index 
    } 

नोट intable

attr(myConn, "case") <- 'nochange' 

यहाँ अधिक विवरण हैं:

समाधान मामले को 'nochange' जब या कनेक्शन के बाद गुण सेट करने के लिए है cname और coldata पर कॉल करें।

0

कुछ मामलों में, विशेष रूप से यदि आप एकाधिक कॉलम पास कर रहे हैं तो आपको स्तंभ नाम के रूप में कॉलम संरचना को स्पष्ट रूप से निर्दिष्ट करने की आवश्यकता है।

उदाहरण: SQLUpdate (myconn, db.df, tablename = 'mytable', सूचकांक = नाम ('आईडी 2'), वर्बोज़ = TRUE)

अद्यतन: तो यह कभी कभी लगता है यह अभी भी विफल रहता है। मेरे द्वारा उपयोग किए जाने वाले नए काम में यह है:

यह आपको आवश्यक होने पर कॉलम की एक सूची पास करने की अनुमति देता है। पता नहीं क्यों यह दूसरी तरफ परिष्कृत था।

indexNames < -List ("आईडी 2")

SQLUpdate (myconn, db.df, tablename = 'mytable', सूचकांक = as.character ("आईडी 2"), वर्बोज़ = TRUE)

संबंधित मुद्दे