我如何左填充一个值?
我遵循将最大长度字符串添加到目标列然后剪掉最后 N 位的模式。在这种情况下,'000000000000000' + 'RTS092' 产生的值是 000000000000000RTS092,这显然太长了,所以我应用右子字符串操作来保留最右边的字符。
我发现这是一种“愚蠢”的方法,但效果很好。很少有逻辑会出错。您可能可以通过仅在需要时以最少的填充量来减少一些微观时间单位,但是这种方法的简单性通常比维持正确的逻辑和保持正确的维护更重要
应用垫
在我看来,这里有 3 种方法:在飞行中对其进行改造,在着陆前对其进行修复,在访问时对其进行翻译。
变换
最明智的方法是在数据出现在表中之前对其进行修复。这就是ETL 的全部T。在 SSIS 中,我将使用以下逻辑将派生列组件添加到我的数据流中
ISNULL(MyCol) ?
REPLICATE(@[User::PadCharacter],@PadLength) :
RIGHT((REPLICATE(@[User::PadCharacter],@[User::PadLength]) + LTRIM(RTRIM(MyCol))),@[User::PadLength])
这是一种通用方法,假设我创建了 2 个 SSIS 级别变量:PadCharacter 和 PadLength。我指定了0 的PadCharacter 和15 的PadLength。如果您发现需要使用填充字符 X 和长度为 20,那么您更改的是值,而不是公式。
它可以正确处理 NULL 值以及两边的空白填充。
在它落地之前修复它
正如 Greg 所说,您可以使用INSTEAD OF 触发器在数据接触表格之前修复数据。我会仅在我无法修复应用程序以防止不良数据进入表格时提倡这种方法。我还将对增加的插入成本进行基准测试,并确保我的业务用户了解对系统的潜在影响。
在访问时翻译它
假设您无法在运行中修复它并且触发器的成本太高,您可以查看在桌子上创建一个computed column。谁在乎我们是否将其存储为“RTS092”,列应用程序访问是使用上面重复的相同公式定义的,以始终向用户显示填充值。
代码大概
ALTER TABLE
dbo.MyTable
ADD
MyComputedCol AS RIGHT(( REPLICATE(N'0',15) + COALESCE(NULLIF(LTRIM(RTRIM(MyCol)), ''), '') ), 15)
比米尔
由于我喜欢展示我的作品,下面的 Biml 将创建上面的包。这确实使用 bimlscript,因为字符串操作会导致发射器难以确定长度,因此我明确地将其强制为具有指定长度的 DT_WSTR 数据类型。下载Bids Helper。添加 .biml 文件,粘贴以下代码,但粘贴时请注意 Visual Studio "helping" you
<Biml xmlns="http://schemas.varigence.com/biml.xsd">
<# int padLength=15;#>
<Connections>
<OleDbConnection Name="CM_OLE" ConnectionString="Data Source=localhost\dev2014;Initial Catalog=tempdb;Provider=SQLNCLI10.1;Integrated Security=SSPI;Auto Translate=False;" />
</Connections>
<Packages>
<Package ConstraintMode="Linear" Name="so_27787812">
<Variables>
<Variable DataType="String" Name="QuerySource">
<![CDATA[SELECT
D.MyCol
FROM
(
VALUES
(N'RTS092')
, (N'3ISUEX')
, (N'ABCDEFGHIJ')
, (N'9485028')
, (N' UGH ')
, (NULL)
)D(MyCol);]]>
</Variable>
<Variable DataType="String" Name="PadCharacter">0</Variable>
<Variable DataType="Int32" Name="PadLength"><#=padLength#></Variable>
</Variables>
<Tasks>
<Dataflow Name="DFT LeftPad">
<Transformations>
<OleDbSource ConnectionName="CM_OLE" Name="OLE_SRC Query">
<VariableInput VariableName="User.QuerySource"></VariableInput>
</OleDbSource>
<!--
Left pad our column with our specified character.
Assumes source column is called MyCol
Creates a new column callec der_MyCol
-->
<DerivedColumns Name="DFT LeftPad">
<Columns>
<Column DataType="String" Name="der_MyCol" Length="<#=padLength#>">ISNULL([MyCol]) ? REPLICATE(@[User::PadCharacter], @PadLength) : RIGHT((REPLICATE(@[User::PadCharacter], @[User::PadLength]) + LTRIM(RTRIM([MyCol]))), @[User::PadLength])</Column>
</Columns>
</DerivedColumns>
<DerivedColumns Name="DFT Do nothing" />
</Transformations>
</Dataflow>
</Tasks>
</Package>
</Packages>
</Biml>