我正在编写一个简单的VBA函数来将输入(从SSMS复制到excel)转换为WHERE子句。像这样:
Imgur /Cannot post directly, sorry/
我已经这样做了,但我偶然发现了两个问题,我要求帮助。
以下是两个问题:
预期:如果我从以下查询中复制结果,则aqwhere_clause函数应生成一个完全如图所示的WHERE子句(在代码中标记)。
with cte ( col1, col2, col3, col4_date ) as (
select N' _1234567890/-+.<>,;:''""][{}\|_!@#$%^& *() ',N'泰Kisk眉头福克斯yumps在Tkhe拉兹狗','',cast('01-01-2015' as date) union ALL
select N' _1234567890/-+.<>,;:''""][{}\|_!@#$%^& *() ',N'abcefghijklmnopqrstuvwxyz' ,'',cast('01-05-2016' as date) union ALL
select N' _1234567890/-+.<>,;:''""][{}\|_!@#$%^& *() ',N'абвгдеёжзиклмнопрстуфхцчшщъыьэюя','',cast('01-06-2019' as date)
)
select *
from cte
/* this is the part that should be generated ( excluding CRLF )*/
where 1=1
and [col1] in (N' _1234567890/-+.<>,;:''""][{}\|_!@#$%^& *() ', N' _1234567890/-+.<>,;:''""][{}\|_!@#$%^& *() ', N' _1234567890/-+.<>,;:''""][{}\|_!@#$%^& *() ')
and [col2] in (N'泰Kisk眉头福克斯yumps在Tkhe拉兹狗', N'abcefghijklmnopqrstuvwxyz', N'абвгдеёжзиклмнопрстуфхцчшщъыьэюя')
and [col3] in (N'', N'', N'')
and [col4_date] in (N'01-01-2015', N'01-05-2016', N'01-06-2019')
/**/
实际: 它生成以下内容:
Imgur /Cannot post directly, sorry/
以文本格式(为了便于阅读,我在AND之前添加了\ r \ n):
where 1=1
and [col1] in (N' _1234567890/-+.<>,;:'""][{}\|_!@#$%^& *() ', N' _1234567890/-+.<>,;:'""][{}\|_!@#$%^& *() ', N' _1234567890/-+.<>,;:'""][{}\|_!@#$%^& *() ')
and [col2] in (N'泰Kisk眉头福克斯yumps在Tkhe拉兹狗', N'abcefghijklmnopqrstuvwxyz', N'абвгдеёжзиклмнопрстуфхцчшщъыьэюя')
and [col3] in (N'', N'', N'')
and [col4_date] in (N'01-Jan-15', N'01-May-16', N'01-Jun-19')
它在[col1]
中吃掉两个单引号中的一个可能的解决方案:替换(cell.value,“'”,“''”)。还有更好的吗? 方式是什么?
它将所有日期格式转换为'DD-MMM-YY'。这个问题是 跨世界网络提到,甚至在这里 stackoverflow。 但我见过的所有解决方案都是关于强制建立日期模式。一世 不能这样做,因为我的输入日期将有不同的日期 格式大部分时间。
可能的解决方案:解析列名称或excel单元格格式(如何?) 确定它是否为日期并强制将列转换为 预定的模式。像这样:
和CONVERT(datetime,[col4_date],6)in(N'01-Jan-15',N'01-May-16',N'01-Jun-19')
这是代码:
Function aqwhere_clause(A_E As Range) As String
Dim Arr As Variant
Arr = A_E
Dim lStrVar As String
Dim i As Long
Dim j As Long
'Where PREFIX
lStrVar = "where 1=1 "
For i = LBound(Arr, 2) To UBound(Arr, 2)
'Getting COLUMN_NAME
lStrVar = lStrVar + "and " + "[" + CStr(Arr(1, i)) + "]"
'IF Array is more than two rows tall then use IN
If UBound(Arr, 1) > 2 Then
lStrVar = lStrVar + " in ("
For j = LBound(Arr, 1) + 1 To UBound(Arr, 1)
'Getting list of COLUMN_VALUES
If CStr(Arr(j, i)) = "NULL" Or CStr(Arr(j, i)) = "Null" Or CStr(Arr(j, i)) = "null" Then
lStrVar = lStrVar + "" + "Null" + ", "
Else: lStrVar = lStrVar + "N'" + CStr(Arr(j, i)) + "', "
End If
Next j
lStrVar = Left(lStrVar, Len(lStrVar) - 2) + ") "
'IF Array has two rows then use EQUALS ( sanity check on single-dimension row should be passed by user )
'Getting list of COLUMN_VALUES
Else: lStrVar = lStrVar + " = N'" + CStr(Arr(2, i)) + "' "
End If
Next i
aqwhere_clause = lStrVar
End Function
谢谢。