Проблемы создания таблицы RODBC sqlSave
у меня возникли проблемы с созданием таблицы с помощью SQLSAVE RODBC (или, точнее, записи данных в созданную таблицу).
это отличается от существующего вопроса/ответов sqlSave, как
- проблемы, которые они испытывали, были разными, я могу создавать таблицы, тогда как они не могли и
- я уже неудачно включил их решения, такие как закрытие и повторное открытие соединения перед запуском sqlSave, также
- сообщение об ошибке отличается, за единственным исключением является сообщение, которое отличалось выше 2 способами
я использую MS SQL Server 2008 и 64-разрядный R в Windows RDP.
у меня есть простой фрейм данных только с 1 столбцом, полным 3, 4 или 5-значными целыми числами.
> head(df)
colname
1 564
2 4336
3 24810
4 26206
5 26433
6 26553
когда я пытаюсь использовать sqlSave, данные не записываются в таблицу. Кроме того, сообщение об ошибке звучит как таблица не может быть создана хотя таблица фактически создается с 0 строками.
основываясь на предложении, которое я нашел, я попытался закрыть и снова открыть соединение RODBC прямо перед запуском sqlSave. Хотя я использую append = TRUE
, Я попытался сбросить таблицу, прежде чем делать это, но это ни на что не влияет.
> sqlSave(db3, df, table = "[Jason].[dbo].[df]", append = TRUE, rownames = FALSE)
Error in sqlSave(db3, df, table = "[Jason].[dbo].[df]", :
42S01 2714 [Microsoft][ODBC SQL Server Driver][SQL Server]There is already
an object named 'df' in the database.
[RODBC] ERROR: Could not SQLExecDirect 'CREATE TABLE [Jason].[dbo].[df]
("df" int)'
я также попытался использовать sqlUpdate () в таблице после ее создания. Не имеет значения, создаю ли я его в R или SQL Server Management Studio, я получаю ошибку table not found on channel
наконец, обратите внимание, что я также пробовал это без добавления = TRUE и при создании новой таблицы, а также с опцией rownames и без нее.
Мистер Флик из Freenode #R заставил меня проверить, могу ли я читать в пустой таблице с помощью sqlQuery, и действительно, я могу.
обновление
я стал немного ближе со следующими шагами:
- я создал соединение ODBC, которое идет непосредственно к моему База данных в SQL Server, а не только в БД по умолчанию (Master), а затем указывает путь к таблице в
table =
илиtablename =
заявления - создал таблицу в среде SQL Server Management Studio следующим образом
GO
CREATE TABLE [dbo].[testing123](
[Person_DIMKey] [int] NULL
) ON [PRIMARY]
GO
в R я использовал
sqlUpdate
С моим новым соединением ODBC и без скобок вокруг tablenameтеперь sqlUpdate () видит таблицу, однако она жалуется, что ей нужен уникальный столбец
указывает, что единственным столбцом в таблице является уникальный столбец с
index = colname
приводит к ошибке, говоря, что столбец не существуетя отбросил и воссоздал таблицу, указав первичный ключ,
GO
CREATE TABLE [dbo].[jive_BNR_Person_DIMKey](
[jive_BNR_Person_DIMKey] [int] NOT NULL PRIMARY KEY
) ON [PRIMARY]
GO
который сгенерировал как первичный ключ, так и индекс (согласно интерфейсу GUI SQL Sever Management Studio) с именем PK__jive_BNR__2754EC2E30F848ED
- я уточнил этот индекс/ключ как уникальный столбец в sqlUpdate() но я получаю следующую ошибку:
Error in sqlUpdate(db4, jive_BNR_Person_DIMKey, tablename = "jive_BNR_Person_DIMKey", :
index column(s) PK__jive_BNR__2754EC2E30F848ED not in database table
для записи я указывал правильное имя столбца (не "colname") для индекса; спасибо MrFlick за запрос разъяснения.
кроме того, эти шаги пронумерованы от 1 до 7 в моем сообщении, но StackOverflow сбрасывает нумерацию списка несколько раз, когда он отображается. Если кто-нибудь может помочь мне очистить этот аспект этого сообщения, я был бы признателен.
6 ответов
после перечитывания RODBC vingette и вот простое решение, которое сработало:
sqlDrop(db, "df", errors = FALSE)
sqlSave(db, df)
сделано.
после экспериментов с этим намного больше в течение нескольких дней, кажется, что проблемы возникли из-за использования дополнительных опций, особенно table =
или, что эквивалентно, tablename =
. Это должны быть допустимые параметры, но каким-то образом им удается вызвать проблемы с моей конкретной версией RStudio ((Windows, 64 бит, настольная версия, текущая сборка), R (Windows, 64 бит, v3) и/или MS SQL Server 2008.
sqlSave(db, df)
также будет работать без sqlDrop(db, "df")
если таблица никогда не существовало, но в качестве лучшей практики, я пишу try(sqlDrop(db, "df", errors = FALSE), silent = TRUE)
прежде всего sqlSave
заявления в моем коде.
после нескольких часов работы над этим я, наконец, смог заставить sqlSave работать, указав имя таблицы-глубокий вдох, с чего начать. Вот список вещей, которые я сделал, чтобы заставить это работать:
- откройте 32-разрядный администратор ODBC и создайте пользовательский DSN и настройте его для конкретной базы данных. В моем случае я создаю глобальную временную таблицу, поэтому я связался с tempdb. Используйте это имя соединения в своем
odbcConnection(Name)
. Вот мой кодmyconn2 <- odbcConnect("SYSTEMDB")
. - затем я определил мои типы данных со следующим кодом:
columnTypes <- list(Record = "VARCHAR(10)", Case_Number = "VARCHAR(15)", Claim_Type = "VARCHAR(15)", Block_Date = "datetime", Claim_Processed_Date = "datetime", Status ="VARCHAR(100)")
. - затем я обновил типы классов фрейма данных с помощью
as.character
иas.Date
для соответствия типам данных, перечисленным выше. - я уже создал таблицу, так как я работал над ней в течение нескольких часов, поэтому мне пришлось удалить таблицу с помощью
sqlDrop(myconn2, "##R_Claims_Data")
. - затем я побежал:
sqlSave(myconn2, MainClmDF2, tablename = "##R_Claims_Data", verbose=TRUE, rownames= FALSE, varTypes=columnTypes)
затем моя голова отвалилась, потому что это сработало! Я очень надеюсь, что это поможет кому-то двигаться вперед. Вот ссылки, которые помогли мне сделать до этого момента:
в дополнение к некоторым ответам, опубликованным ранее, вот мой обходной путь. Примечание: Я использую это как часть небольшого процесса ETL, и таблица назначения в БД отбрасывается и воссоздается каждый раз.
в основном вы хотите назвать свой фрейм данных, как называется таблица назначения:
RodbcTest <- read.xlsx('test.xlsx', sheet = 4, startRow = 1, colNames = TRUE, skipEmptyRows = TRUE)
затем убедитесь, что строка подключения включает целевую базу данных (а не только сервер):
conn <- odbcDriverConnect(paste("DRIVER={SQL Server};Server=localhost\sqlexpress;Database=Charter;Trusted_Connection=TRUE"))
после этого я запускаю простой sqlQuery, который условно удаляет таблицу, если она существует:
sqlQuery(conn, "IF OBJECT_ID('Charter.dbo.RodbcTest') IS NOT NULL DROP TABLE Charter.dbo.RodbcTest;")
затем, наконец, запустите sqlSave без параметра tablename, который создаст таблицу и заполнит ее вашим фреймом данных:
sqlSave(conn, RodbcTest, safer = FALSE, fast = TRUE)
у нас была такая же проблема, что после небольшого тестирования мы решили просто не использовать квадратные скобки в ссылке на имя схемы и таблицы.
т. е. вместо того, чтобы писать
table = "[Jason].[dbo].[df]"
вместо того, чтобы писать
table = "Jason.dbo.df"
оцените, что это уже давно прошло первоначальный вопрос, но только для тех, кто впоследствии натыкается на эту проблему, вот как мы ее решили. Для справки, мы узнали это, написав простой 1 пункт dataframe к новой таблице, которая при проверке в SQL содержала квадратные скобки в имени таблицы.
вот несколько правил:
- если что-то не работает, то вручную укажите типы столбцов так же, как @d84_n1nj4 предложил.
columnTypes <- list(Record = "VARCHAR(10)", Case_Number = "VARCHAR(15)", Claim_Type = "VARCHAR(15)", Block_Date = "datetime", Claim_Processed_Date = "datetime", Status ="VARCHAR(100)")
sqlSave(myconn2, MainClmDF2, tablename = "##R_Claims_Data", verbose=TRUE, rownames= FALSE, varTypes=columnTypes)
- если #1 не работает, продолжайте указывать столбцы, но укажите их все как
VARCHAR(255)
. Рассматривайте это как временную или промежуточную таблицу и перемещайте данные с помощьюsqlQuery
С вашим следующим шагом, так же, как @danas.Зуокас!--15--> предложил. Это должно работать, но даже если это не так, это приближает вас к металлу и ставит вас в лучшее положение для отладки проблемы с SQL Server Profiler, если вам это нужно.
columnTypes <- list(Record = "VARCHAR(255)", Case_Number = "VARCHAR(255)", Claim_Type = "VARCHAR(255)", Block_Date = "VARCHAR(255)", Claim_Processed_Date = "VARCHAR(255)", Status ="VARCHAR(255)")
sqlSave(myconn2, MainClmDF2, tablename = "##R_Claims_Data", verbose=TRUE, rownames= FALSE, varTypes=columnTypes)
sqlQuery(channel, 'insert into real_table select * from R_Claims_Data')
- из-за реализации RODBC и не из-за любого неотъемлемого ограничения в T-SQL, Р
logical
тип (т. е.[TRUE, FALSE]
) не будет преобразование в T-SQLBIT
введите (т. е. [1, 0]), поэтому не пытайтесь это сделать. Либо преобразоватьlogical
введите [1, 0] в слое R или перенесите его на уровень SQL какVARCHAR(5)
и преобразовать его вBIT
в слое SQL.
я столкнулся с той же проблемой-так, как я нашел вокруг нее, чтобы создать пустую таблицу с помощью regular CREATE TABLE
синтаксис SQL, а затем добавьте к нему через sqlSave
. По какой - то причине, когда я попробовал это по - вашему, я мог видеть имя таблицы в базе данных MSSQL-даже после того, как R выбросил сообщение об ошибке, которое вы показали выше, - но оно было бы пустым.