【问题标题】:Unable to import to Excel using OPENROWSET in SQL Server 2008 R2无法在 SQL Server 2008 R2 中使用 OPENROWSET 导入 Excel
【发布时间】:2013-03-11 00:11:49
【问题描述】:

我必须将 Excel 模板复制到另一个文件夹才能导入数据。以下是我正在使用的两个 SQL 语句:

声明1:

exec xp_cmdshell 'copy C:\inetpub\wwwroot\app_data\export_templates\myExport.xlsx C:\inetpub\wwwroot\app_data\tmp\myExport130301172218.xls'

声明2:

insert into 
OPENROWSET('Microsoft.ACE.OLEDB.12.0'
    , 'Excel 12.0;Database=C:\inetpub\wwwroot\app_data\tmp\myExport130301172218.xls;'
    , 'SELECT * FROM [Sheet1$]')  
SELECT * FROM vw_shrub 

如果我单独执行上述 SQL 语句,它们就可以正常工作。但是如果我一起执行它们,则会引发以下错误:

链接服务器“(null)”的 OLE DB 提供程序“Microsoft.ACE.OLEDB.12.0”返回消息“Microsoft Access 数据库引擎找不到对象 'Sheet1$'。请确保该对象存在并且您拼写它的名称和路径名正确。如果“Sheet1$”不是本地对象,请检查您的网络连接或联系服务器管理员。”。

消息 7350,第 16 层,状态 2,第 2 行
无法从链接服务器“(null)”的 OLE DB 提供程序“Microsoft.ACE.OLEDB.12.0”获取列信息。

问题是我想从我的应用程序中将它们作为单个请求传递。因此,我必须一起执行它们。我发现如果我在它们之间添加 GO,我可以在 Management Studio 中一起执行它们。但是当我传递来自我的应用程序的请求时,我无法使用 GO。

【问题讨论】:

  • 为什么副本中的路径与OPENROWSET中的路径不同
  • 对不起斯佩特。当我在我的问题中编写示例时,这是一个错误。但问题仍然存在。我更新了问题。谢谢。
  • 为什么不创建一个存储过程并从您的应用程序中调用该过程
  • 嗨,Raymund,我不确定我是否明白你的意思,但这实际上是我正在做的。我将上述代码的两部分作为一个存储过程运行。
  • 使用xp_cmdshellgenerally considered bad practice,尤其是在应用程序中。就我个人而言,我不会在 SQL Server 中执行任何。您必须考虑到数据库服务器和应用程序服务器通常不是同一台计算机这一事实。我会获取数据并从应用程序本身构建它。话题上有other questions

标签: sql-server-2008


【解决方案1】:

另一种方法是在 SQL Server 代理作业中将这两行分成两个不同的步骤,并使用一条指令执行它:

sp_start_job nameOfYourJob

工作的两个步骤就像中间有一个 GO。

【讨论】:

  • 好点 Zelloss。但我的问题是为什么当你同时运行这两个语句时 SQL Server 的行为会有所不同。这种行为有什么合乎逻辑的解释吗?当它与 GO 语句一起使用时,这意味着一切正常,没有权限问题,语法也正确。但是为什么它必须在两个不同的语句中运行呢?
  • 我的猜测是它没有时间结束复制,因为它是一个异步指令,并且插入发现 excel 被锁定或仍在复制,就像你尝试插入你自己的 excel保持打开状态。也许这可以通过在复制和插入之间的同一目录上创建exec xp_cmdshell 'dir' 进行测试。
  • 这可能是正确的答案。但我想知道是否是这种情况,至少应该在最后复制空文件。你不觉得吗?
  • 嗯,你是对的。我想不出另一个测试来进一步了解发生了什么。我会及时通知你。
【解决方案2】:

你有没有试过在 exec 语句后加一个 GO?

您连接到 SQL Server 的帐户是否具有对 SQL Temp 目录的读/写访问权限?我的理解是 SQL 会将 xls 文件复制到它的临时目录,如果您的用户没有管理员权限或 Windows 对临时目录的读/写权限,则连接将失败。

【讨论】:

  • 连接到sql server。正如我所提到的,如果我在 mng studio 中使用 Go,它就可以工作。但我不能在我的代码中的 t-sql 中使用它
  • 你可能误会了。如果您使用用户帐户 BlahBlah 连接到 SQL Server,BlahBlah 是否具有对 SQL Server 临时目录的读/写访问权限(不确定路径是什么,但类似于 C:\Program Files\Microsoft\SQL Server\10.0\temp)?
  • 用户帐户具有读/写权限。正如您在上面的解释中所看到的,如果我运行 statement1 和 statement2 并在其间添加一个 GO,它会完美运行。但是如果我删除 GO 行,它就不起作用。对我来说,这意味着没有权限问题,因为两种情况都使用相同的用户名
  • 它们之间的 GO 语句执行批处理。它运行重命名语句,然后加载数据。否则,它会尝试一步完成,而不是它需要的两个。让一个查询具有 xp_cmdshell... GO Insert Into... GO 是否存在问题?
  • 我明白这一点。但问题是如何同时运行这两个语句?使用 Go 的问题是,当我在 SQL Server Management Studio 中使用它时它是可以的,但我不能在我的代码中的 T-SQL 中使用它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-16
相关资源
最近更新 更多