sql - 在 Sql 查询中使用单元格中的日期或命名范围

标签 sql sql-server excel vba

我创建了一张表格来从 Microsoft SQL 数据库中提取数据,以在 2 日期 StartDate 之间生成客户报告和 EndDate .

我一直在玩一些东西,但无论如何都没有成功。我已经搜索过,但找不到任何我想要或能够理解的东西。

我认为的问题是我在 Excel 中使用的日期的数据类型,并试图将其传递给 SQL 查询。我知道我需要以某种方式对其进行转换以使其成为可能且正确。

如果我在查询中手动输入日期,它工作正常。但不适合客户使用
我没有这方面的经验,我只是!用我的方式通过它。如果有人对我这么好,将不胜感激。

下面是我尝试使用的代码

Sub DataExtract()
'
DataExtract Macro
'

' Create a connection object.
 Dim cni96X As ADODB.Connection
 Set cni96X = New ADODB.Connection

' Set Database  Range

' Provide the connection string.
Dim strConn As String
Dim Lan As Integer
Dim OS As Integer
Dim PointID As String


' Set Variables
Lan = Range("Lan").Value
OS = Range("OS").Value
PointID = Range("PointID").Value
StartDate = Range("StartDate").Value
EndDate = Range("EndDate").Value


'Use the SQL Server OLE DB Provider.
 strConn = "PROVIDER=SQLOLEDB;"

'Connect to 963 database on the local server.
strConn = strConn & "DATA SOURCE=(local);INITIAL CATALOG=i96X;"

'Use an integrated login.
strConn = strConn & " INTEGRATED SECURITY=sspi;"

 'Now open the connection.
cni96X.Open strConn

' Create a recordset object.
Dim rsi96X As ADODB.Recordset
Dim rsi96X1 As ADODB.Recordset
Set rsi96X = New ADODB.Recordset
Set rsi96X1 = New ADODB.Recordset

With rsi96X
    ' Assign the Connection object.
     .ActiveConnection = cni96X
    ' Extract the required records1.
    .Open "SELECT ModuleLabel, originalAlarmTime FROM LastAlarmDetailsByTime WHERE (os = " & OS & " And theModule = N'" & PointID & "'AND AlarmCode = N'DI=1' And lan = " & Lan & " And originalAlarmTime BETWEEN N'" & StartDate & "' AND N'" & EndDate & "') ORDER BY originalAlarmTime DESC"
    ' Copy the records into sheet.
    Range("PointLabel, TimeCallInitiated").CopyFromRecordset rsi96X


With rsi96X1
    .ActiveConnection = cni96X
    ' Assign the Connection object.
    .Open "SELECT originalAlarmTime FROM LastAlarmDetailsByTime WHERE (os = " & OS & " And theModule = N'" & PointID & "'AND AlarmCode = N'CDI1' And lan = " & Lan & " And originalAlarmTime BETWEEN N'" & StartDate & "' AND N'" & EndDate & "')ORDER BY originalAlarmTime DESC"
     ' Copy the records into sheet.
    Sheet1.Range("TimeCallEnded").CopyFromRecordset rsi96X1
    ' Tidy up
    .Close

我希望这是有道理的。

最佳答案

您不能指定数据类型,Access 数据库引擎(以前称为 Jet)必须猜测。您可以通过更改某些注册表设置(例如 MaxScanRows )并包括 IMEX=1 来影响其猜测。在连接字符串中。更多详情,请参阅 this knowledge base article .

这是我多年前就这个主题写的一些东西(如果你用谷歌搜索“ONEDAYWHEN=0”,你会发现它已被广泛阅读,尽管可能不够仔细!):

相关的注册表项(用于 Jet 4.0)位于:

Hkey_Local_Machine/Software/Microsoft/Jet/4.0/Engines/Excel/
ImportMixedTypes注册表项总是被读取(无论是
荣誉将在后面讨论)。您可以通过将 key 更改为ImportMixedTypes=OneDayWhen并尝试使用 ISAM:你得到了
错误,“引擎部分的 Excel 键中的设置无效
Windows 注册表。”唯一有效的值是:

  • ImportMixedTypes=Text
  • ImportMixedTypes=Majority Type

  • 数据类型是逐列确定的。 “多数类型”是指
    扫描每列中的一定数量的行(稍后会详细介绍)
    并计算数据类型。单元格的值和格式都是
    用于确定数据类型。多数数据类型(即具有
    最多行)决定整个列的整体数据类型。
    如果出现平局,则存在偏向于 os numeric 的偏见。来自的行
    发现的任何少数数据类型无法转换为多数数据
    type 将返回一个空值。

    对于 ImportMixedTypes=Text ,整列的数据类型将是:
    Jet (MS Access UI): 'Text' data type 
    DDL: VARCHAR(255) 
    ADO: adWChar ('a null-terminated Unicode character string') 
    

    请注意,这不同于:
    Jet (MS Access UI): 'Memo' data type 
    DDL: MEMO 
    ADO: adLongVarWChar ('a long null-terminated Unicode string value') 
    
    ImportMixedTypes=Text将 255 个字符的文本缩减为 Memo
    转换为 Text .对于要识别为 Memo 的列, 多数型
    必须检测到,这意味着检测到的大多数行必须包含
    256 个或更多字符。

    但是之前每列扫描了多少行是由决定的
    混合和/或多数类型是什么?有第二个注册表
    键,TypeGuessRows .这可以是 0-16(十进制)之间的值。一个值
    从 1 到 16(含)是要扫描的行数。零值
    表示将扫描所有行。

    最后有一个转折。 IMEX=1 的设置在连接中
    字符串的扩展属性决定 ImportMixedTypes值(value)得到尊重。 IMEX指“导入导出模式”。有三种
    可能的值。 IMEX=0IMEX=2结果 ImportMixedTypes存在
    忽略并使用“多数类型”的默认值。 IMEX=1
    确保ImportMixedTypes=Text的唯一方法很荣幸。所结果的
    连接字符串可能如下所示:
    Provider=Microsoft.Jet.OLEDB.4.0; 
    Data Source=C:\ db.xls; 
    Extended Properties='Excel 8.0;HDR=Yes;IMEX=1' 
    

    最后,虽然在 MSDN 文章中提到 MAXSCANROWS可以在连接字符串的扩展属性中使用
    覆盖 TypeGuessRows 注册表项,这似乎是一个谬论。
    使用 MAXSCANROWS=0以这种方式从不做任何事情
    情况。换句话说,is 和 put 的效果一样ONEDAYWHEN=0在扩展属性中,没有(甚至不是
    错误!)同样适用于ImportMixedTypes即不能用于
    覆盖注册表设置的连接字符串。

    总之,使用 TypeGuessRows让 Jet 检测是否有“混合
    类型的情况存在或使用它来“欺骗”Jet 检测到
    某些数据类型是多数类型。如果发生
    检测到“混合类型”的情况,使用 ImportMixedTypes告诉
    Jet 使用多数类型或将所有值强制为 Text(最多 255 个字符)。

    关于sql - 在 Sql 查询中使用单元格中的日期或命名范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10100724/

    相关文章:

    javascript - 当 while 循环和行变量满足条件时,如何循环它们?

    包含用户、角色和权限的 SQL SELECT 语句

    php - 如何使用 SQL Server 存储和检索图像 (Server Management Studio)

    string - Excel 2010 VBA 单步执行字符串并按顺序将一个字符放入每个单元格中

    php - Composer 要求 phpoffice/phpspreadsheet 不起作用

    java - JPA Spring 查询 sql

    sql - T-SQL 动态枢轴

    sql-server - 具有重复 NULL 的 SQL Server UNIQUE 约束

    sql - 从 sp_addlinkedserver 访问服务器

    excel - Excel中的西格玛函数