内联 T-SQL OR 子查询
Inline T-SQL OR subquery
试图找出在内联 SQL 语句中使用子查询的最有效方法。内联 SQL 不是我的经验,但我在我的组织中别无选择,唉。
SELECT *
FROM dbo.VW_RMISPayment
WHERE ProcDate BETWEEN '7/2/2018' AND '3/8/2019'
AND Status = 'P'
AND Fund = '359'
AND Amount > 0
AND (BatchNotate = 'B' OR BatchNotate IS NULL)
ORDER BY ProcDate, Amount
如何参数化 (BatchNotate = 'B' OR BatchNotate IS NULL)
部分?
我的变量作为 List<string>
传入,但我可以将其更改为任何内容。我只是不确定如何从我的变量
创建这个子查询
if (BatchNotate.Count() > 0)
{
query += " AND BatchNotate= @BatchNotate";
}
cmd.Parameters.AddWithValue("@BatchNotate", batchNotate);
你能做这样的事情吗?
SELECT *
FROM dbo.VW_RMISPayment
WHERE ProcDate BETWEEN '7/2/2018' AND '3/8/2019'
AND Status = 'P'
AND Fund = '359'
AND Amount > 0
AND BatchNotate = COALESCE(@BatchNotate, BatchNotate)
ORDER BY ProcDate, Amount
使用这个:
BatchNotate = COALESCE(@inVariable,'B')
如果变量 (@inVariable) 为 null,则它将“默认为 B。
如果是其他东西,它将与那个东西进行比较。
这些都不能满足我的需求。这是我最终要做的。这有点 hacky,但它确实有效。
public static string AddParametersOR<T>(SqlParameterCollection parameters,
string fieldName,
string pattern,
SqlDbType parameterType,
int length,
IEnumerable<T> values)
{
if (parameters == null)
throw new ArgumentNullException("parameters");
if (pattern == null)
throw new ArgumentNullException("pattern");
if (values == null)
throw new ArgumentNullException("values");
if (!pattern.StartsWith("@", StringComparison.CurrentCultureIgnoreCase))
throw new ArgumentException("Pattern must start with '@'");
var parameterNames = new List<string>();
foreach (var item in values)
{
var parameterName = parameterNames.Count.ToString(pattern, CultureInfo.InvariantCulture);
string parameterWithFieldName = string.Empty;
if (item.ToString().ToUpper() == "NULL")
{
parameterWithFieldName = string.Format("{0} IS NULL", fieldName);
}
else if (item.ToString().ToUpper() == "NOTNULL")
{
parameterWithFieldName = string.Format("{0} IS NOT", fieldName);
}
else
{
parameterWithFieldName = string.Format("{0}= {1}", fieldName, parameterName);
}
parameterNames.Add(parameterWithFieldName);
parameters.Add(parameterName, parameterType, length).Value = item;
}
return string.Join(" OR ", parameterNames.ToArray());
}
用法:
if (batchNotate.Count() > 0)
{
query += " AND ({@BatchNotate})";
}
string batchNotateParamNames = SqlHelper.AddParametersOR(cmd.Parameters, "BatchNotate", "@B0", SqlDbType.VarChar, 1, batchNotate);
cmd.CommandText = query.Replace("{@BatchNotate}", batchNotateParamNames);
根据列表中的项目数量,输出将如下所示:
(BatchNotate= 'B' 或 BatchNotate= 'N' 或 BatchNotate 为空)
如果找到 "NULL" 或 "NOTNULL",它将用 IS NULL 或 IS NOT NULL
替换它们
试图找出在内联 SQL 语句中使用子查询的最有效方法。内联 SQL 不是我的经验,但我在我的组织中别无选择,唉。
SELECT *
FROM dbo.VW_RMISPayment
WHERE ProcDate BETWEEN '7/2/2018' AND '3/8/2019'
AND Status = 'P'
AND Fund = '359'
AND Amount > 0
AND (BatchNotate = 'B' OR BatchNotate IS NULL)
ORDER BY ProcDate, Amount
如何参数化 (BatchNotate = 'B' OR BatchNotate IS NULL)
部分?
我的变量作为 List<string>
传入,但我可以将其更改为任何内容。我只是不确定如何从我的变量
if (BatchNotate.Count() > 0)
{
query += " AND BatchNotate= @BatchNotate";
}
cmd.Parameters.AddWithValue("@BatchNotate", batchNotate);
你能做这样的事情吗?
SELECT *
FROM dbo.VW_RMISPayment
WHERE ProcDate BETWEEN '7/2/2018' AND '3/8/2019'
AND Status = 'P'
AND Fund = '359'
AND Amount > 0
AND BatchNotate = COALESCE(@BatchNotate, BatchNotate)
ORDER BY ProcDate, Amount
使用这个:
BatchNotate = COALESCE(@inVariable,'B')
如果变量 (@inVariable) 为 null,则它将“默认为 B。
如果是其他东西,它将与那个东西进行比较。
这些都不能满足我的需求。这是我最终要做的。这有点 hacky,但它确实有效。
public static string AddParametersOR<T>(SqlParameterCollection parameters,
string fieldName,
string pattern,
SqlDbType parameterType,
int length,
IEnumerable<T> values)
{
if (parameters == null)
throw new ArgumentNullException("parameters");
if (pattern == null)
throw new ArgumentNullException("pattern");
if (values == null)
throw new ArgumentNullException("values");
if (!pattern.StartsWith("@", StringComparison.CurrentCultureIgnoreCase))
throw new ArgumentException("Pattern must start with '@'");
var parameterNames = new List<string>();
foreach (var item in values)
{
var parameterName = parameterNames.Count.ToString(pattern, CultureInfo.InvariantCulture);
string parameterWithFieldName = string.Empty;
if (item.ToString().ToUpper() == "NULL")
{
parameterWithFieldName = string.Format("{0} IS NULL", fieldName);
}
else if (item.ToString().ToUpper() == "NOTNULL")
{
parameterWithFieldName = string.Format("{0} IS NOT", fieldName);
}
else
{
parameterWithFieldName = string.Format("{0}= {1}", fieldName, parameterName);
}
parameterNames.Add(parameterWithFieldName);
parameters.Add(parameterName, parameterType, length).Value = item;
}
return string.Join(" OR ", parameterNames.ToArray());
}
用法:
if (batchNotate.Count() > 0)
{
query += " AND ({@BatchNotate})";
}
string batchNotateParamNames = SqlHelper.AddParametersOR(cmd.Parameters, "BatchNotate", "@B0", SqlDbType.VarChar, 1, batchNotate);
cmd.CommandText = query.Replace("{@BatchNotate}", batchNotateParamNames);
根据列表中的项目数量,输出将如下所示:
(BatchNotate= 'B' 或 BatchNotate= 'N' 或 BatchNotate 为空)
如果找到 "NULL" 或 "NOTNULL",它将用 IS NULL 或 IS NOT NULL
替换它们