Tsql 当字符串中缺少或没有默认值时,如何有条件地解析该值
我想有条件地确定字符串中是否有默认值(下面映射字符串中第三个值中的零) 我有以下字符串:Tsql 当字符串中缺少或没有默认值时,如何有条件地解析该值,tsql,parsing,replace,sql-server-2017,isnullorempty,Tsql,Parsing,Replace,Sql Server 2017,Isnullorempty,我想有条件地确定字符串中是否有默认值(下面映射字符串中第三个值中的零) 我有以下字符串: 'PriceSrc|PriceTrg|0;CurrencySrc|CurrencyTrg|0;ProductSrc|ProductTrg|0' 上面表示由分号分隔的SourceColumn | TargetColumn | DefaultValue。因此,我的字符串中有两个分隔符——一个管道和一个分号 我正在分离我的源、目标和默认列,它在下面的代码中运行良好: DECLARE @Mapping NVARC
'PriceSrc|PriceTrg|0;CurrencySrc|CurrencyTrg|0;ProductSrc|ProductTrg|0'
上面表示由分号分隔的SourceColumn | TargetColumn | DefaultValue。因此,我的字符串中有两个分隔符——一个管道和一个分号
我正在分离我的源、目标和默认列,它在下面的代码中运行良好:
DECLARE @Mapping NVARCHAR(max) = 'PriceSrc|PriceTrg|0;CurrencySrc|CurrencyTrg|0;ProductSrc|ProductTrg|0'
DECLARE @SourceTableColumns VARCHAR(256)
DECLARE @TargetTableColumns VARCHAR(256)
DECLARE @DefaultTableColumn VARCHAR(256)
SELECT @SourceTableColumns = isnull(@SourceTableColumns + ',', '') + SourceTableColumn
,@TargetTableColumns = isnull(@TargetTableColumns + ',', '') + TargetTableColumn
,@DefaultTableColumn = isnull(@DefaultTableColumn + ',', '') + DefaultTableColumn
FROM (
SELECT parsename(replace(value, '|', '.'), 3) AS SourceTableColumn
,parsename(replace(value, '|', '.'), 2) AS TargetTableColumn
,parsename(replace(value, '|', '.'), 1) AS DefaultTableColumn
FROM (
SELECT *
FROM String_split(@Mapping,';')
) a
WHERE value <> ' '
) a
print 'Mapping: ' + @Mapping
print 'Source: ' + @SourceTableColumns
print 'Target: ' + @TargetTableColumns
print 'Default: ' + @DefaultTableColumn
但是,当我甚至缺少一个默认值时,比如下面(请注意,我已经排除了字符串末尾的一个零)
我的整个逻辑崩溃了,它清空了我所有的变量。它给出了以下结果(仅我的映射):
请注意,默认值第三个参数的功能是作为覆盖值,供用户选择输入任何字符串或数值。我不想总是强制默认值为NULL,因为它并不总是必需的
如何使映射字符串中的默认值(即DefaultTableColumn)具有条件?如前所述,我可能并不总是有默认值,但我仍然希望保持@SourceTableColumns和@TargetTableColumns变量不变
Zohar Peled提出的修改逻辑:
SELECT @SourceTableColumns = isnull(@SourceTableColumns + ',', '') + SourceTableColumn
,@TargetTableColumns = isnull(@TargetTableColumns + ',', '') + TargetTableColumn
,@DefaultTableColumn = isnull(@DefaultTableColumn + ',', '') + DefaultTableColumn
FROM (
SELECT
JSON_VALUE(JsonMapping, '$.V[0]') As SourceTableColumn,
JSON_VALUE(JsonMapping, '$.V[1]') As TargetTableColumn,
NULLIF(JSON_VALUE(JsonMapping, '$.V[2]'), '') As DefaultTableColumn
FROM String_split(@Mapping, ';')
CROSS APPLY
(
SELECT '{"V":["' + REPLACE([value], '|', '", "') +'"]}' As JsonMapping
) JsonData
) a
print 'Mapping: ' + @Mapping
print 'Source: ' + @SourceTableColumns
print 'Target: ' + @TargetTableColumns
print 'Default: ' + @DefaultTableColumn
以下是我得到的结果:
Mapping: PriceSrc|PriceTrg|0;CurrencySrc|CurrencyTrg|0;ProductSrc|ProductTrg|
Source: PriceSrc,CurrencySrc,ProductSrc
Target: PriceTrg,CurrencyTrg,ProductTrg
我没有得到正确的结果,因为我得到了DefaultTableColumn的所有空值
@DefaultTableColumn的预期值为0,0
问候,,
Shawn首先,自2016版以来,SQL Server具有内置功能 其次,我可能会使用从字符串生成json数组, 然后获取值:
DECLARE @Mapping NVARCHAR(max) = 'PriceSrc|PriceTrg|0;CurrencySrc|CurrencyTrg|0;ProductSrc|ProductTrg|'
SELECT JSON_VALUE(JsonMapping, '$.V[0]') As SourceColumn,
JSON_VALUE(JsonMapping, '$.V[1]') As TargetColumn,
-- json_value returns an empty string if no value found, nullif converts it to a null
NULLIF(JSON_VALUE(JsonMapping, '$.V[2]'), '') As DefaultValue
FROM string_split(@Mapping, ';')
CROSS APPLY
(
SELECT '{"V":["' + REPLACE([value], '|', '", "') +'"]}' As JsonMapping
) As JsonData
结果:(请注意,缺少最后一个默认值)
更新要将结果转换为变量,您可以使用另一个内置函数(自2017年版本起),名为:
您可以在上看到现场演示,谢谢您的回复!我喜欢你的逻辑。如何通过保持变量赋值(SourceTableColumns、TargetTableColumns和DefaultTableColumn)与您的逻辑保持一致来保存代码?就像您之前所做的那样:
select@SourceTableColumns=JSON_值(JsonMapping,$.V[0]),@TargetTableColumns=JSON_值(JsonMapping,$.V[1])…
Zohar,我已经将您的逻辑与我的集成在一起(更新了我的原始问题),但是,我得到了所有默认值的空值。你能告诉我我做错了什么吗?Zohar,如果我删除NULLIF,使我将JSON_值(JsonMapping,$.V[2]”作为DefaultTableColumn,代码工作并给出默认值:0,0,Zohar,那太好了。现在效果好多了。我用一个更简单的版本再次更新了我的答案(将外部选择与内部选择结合起来)
SELECT @SourceTableColumns = isnull(@SourceTableColumns + ',', '') + SourceTableColumn
,@TargetTableColumns = isnull(@TargetTableColumns + ',', '') + TargetTableColumn
,@DefaultTableColumn = isnull(@DefaultTableColumn + ',', '') + DefaultTableColumn
FROM (
SELECT
JSON_VALUE(JsonMapping, '$.V[0]') As SourceTableColumn,
JSON_VALUE(JsonMapping, '$.V[1]') As TargetTableColumn,
NULLIF(JSON_VALUE(JsonMapping, '$.V[2]'), '') As DefaultTableColumn
FROM String_split(@Mapping, ';')
CROSS APPLY
(
SELECT '{"V":["' + REPLACE([value], '|', '", "') +'"]}' As JsonMapping
) JsonData
) a
print 'Mapping: ' + @Mapping
print 'Source: ' + @SourceTableColumns
print 'Target: ' + @TargetTableColumns
print 'Default: ' + @DefaultTableColumn
Mapping: PriceSrc|PriceTrg|0;CurrencySrc|CurrencyTrg|0;ProductSrc|ProductTrg|
Source: PriceSrc,CurrencySrc,ProductSrc
Target: PriceTrg,CurrencyTrg,ProductTrg
DECLARE @Mapping NVARCHAR(max) = 'PriceSrc|PriceTrg|0;CurrencySrc|CurrencyTrg|0;ProductSrc|ProductTrg|'
SELECT JSON_VALUE(JsonMapping, '$.V[0]') As SourceColumn,
JSON_VALUE(JsonMapping, '$.V[1]') As TargetColumn,
-- json_value returns an empty string if no value found, nullif converts it to a null
NULLIF(JSON_VALUE(JsonMapping, '$.V[2]'), '') As DefaultValue
FROM string_split(@Mapping, ';')
CROSS APPLY
(
SELECT '{"V":["' + REPLACE([value], '|', '", "') +'"]}' As JsonMapping
) As JsonData
SourceColumn TargetColumn DefaultValue
PriceSrc PriceTrg 0
CurrencySrc CurrencyTrg 0
ProductSrc ProductTrg NULL
DECLARE @Mapping NVARCHAR(max) = 'PriceSrc|PriceTrg|0;CurrencySrc|CurrencyTrg|0;ProductSrc|ProductTrg|',
@SourceTableColumns NVARCHAR(max),
@TargetTableColumns NVARCHAR(max),
@DefaultTableColumn NVARCHAR(max)
SELECT @SourceTableColumns = STRING_AGG(JSON_VALUE(JsonMapping, '$.V[0]'), ',')
,@TargetTableColumns = STRING_AGG(JSON_VALUE(JsonMapping, '$.V[1]'), ',')
,@DefaultTableColumn = STRING_AGG(NULLIF(JSON_VALUE(JsonMapping, '$.V[2]'), ''), ',')
FROM String_split(@Mapping, ';')
CROSS APPLY
(
SELECT '{"V":["' + REPLACE([value], '|', '", "') +'"]}' As JsonMapping
) As JsonData
print 'Mapping: ' + @Mapping
print 'Source: ' + @SourceTableColumns
print 'Target: ' + @TargetTableColumns
print 'Default: ' + @DefaultTableColumn