如果在数据输入期间未输入最大字符数,如何创建一个表格,其中每列将使用零填充。 我知道如何在数据输入表格后填充,但我不知道在数据输入过程中如何填充。
...示例
导入定义为nvarchar(15)...
的列的值RTS092
3ISUEX
ABCDEFGHIJ
9485028
数据输入/导入后,在表中存储的值....
000000000RTS092
0000000003ISUEX
00000ABCDEFGHIJ
000000009485028
答案 0 :(得分:2)
我遵循将最大长度字符串添加到目标列然后剪掉最后N位的模式。在这种情况下,' 000000000000000' +' RTS092'产生000000000000000RTS092
的值显然太长,所以我应用右子串操作来保留最右边的字符。
我发现这是一个愚蠢的"方法,但它运作良好。错误的逻辑非常少。您可以通过仅在需要时进行填充来削减一些微观时间单位,并且通过最小的数量,但是通过这种方法的简单性,通常可以维持正确地保持正确并保持正确
正如我所看到的,这里有3种方法:在飞行中对其进行转换,在着陆之前修复它,在进入时进行翻译。
最理智的方法是在数据落入表格之前修复数据。那是T
ETL
的全部ISNULL(MyCol) ?
REPLICATE(@[User::PadCharacter],@PadLength) :
RIGHT((REPLICATE(@[User::PadCharacter],@[User::PadLength]) + LTRIM(RTRIM(MyCol))),@[User::PadLength])
。在SSIS中,我将使用以下逻辑
0
这是一种通用方法,假设我创建了2个SSIS级别变量:PadCharacter和PadLength。我指定了15
的PadCharacter和INSTEAD OF
的PadLength。如果您发现需要使用X和20长度的填充字符,则可以更改您的值,而不是公式。
它正确处理NULL值以及任一方的空白填充。
正如Greg所说,你可以使用ALTER TABLE
dbo.MyTable
ADD
MyComputedCol AS RIGHT(( REPLICATE(N'0',15) + COALESCE(NULLIF(LTRIM(RTRIM(MyCol)), ''), '') ), 15)
触发器在数据触及表格之前修复数据。如果我有无法修复的应用程序来阻止不良数据到达表格,我只会 提倡这种方法。我还会对增加的插入成本进行基准测试,并确保我的业务用户了解对系统的潜在影响。
假设您无法在飞行中修复它并且触发器的成本太高,您可以查看在表格上创建computed column。谁关心我们是否将其存储为RTS092',列应用程序访问权限是使用上面重复的相同公式定义的,以便始终向用户显示填充值。
代码约
<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>
由于我是展示我作品的粉丝,以下Biml将创建上述包。这确实使用了bimlscript,因为字符串操作会导致发射器频繁地确定长度,因此我明确地强制它为具有指定长度的DT_WSTR数据类型。下载Bids Helper。添加.biml文件,粘贴以下代码,但在粘贴时注意Visual Studio "helping" you
{{1}}
答案 1 :(得分:0)
right('000000000000000'+ rtrim(@str), 15)
其中@str是字符串。就查询而言,
SELECT COL, right(('000000000000000'+ rtrim(COL)), 15) PaddedString FROM YourTable
来源:Most efficient T-SQL way to pad a varchar on the left to a certain length?
如果要在数据进入表之前实现填充,您可以拥有原始数据所在的临时表,然后处理并将数据移动到第二个表。或者在源处应用上述方法,以便构建它然后进入目标表。这里YourTable
将是源表。
答案 2 :(得分:0)
你可能不应该在你的数据库中这样做,但是在提交数据的应用程序中,但如果你必须在db中这样做,我建议你在插入时使用类似的东西来执行它以下内容:
CREATE TRIGGER myTriggerINSERT
ON myTableName
INSTEAD OF INSERT
AS
DECLARE @myField NVARCHAR(15)
SET @myField = (SELECT myField FROM inserted)
INSERT myTableName (myField) VALUES(right('000000000000000'+ rtrim(@myField), 15))