使用零将默认表值设置为左侧焊盘

时间:2015-01-05 21:00:05

标签: sql-server tsql ssis

如果在数据输入期间未输入最大字符数,如何创建一个表格,其中每列将使用零填充。 我知道如何在数据输入表格后填充,但我不知道在数据输入过程中如何填充。

...示例

导入定义为nvarchar(15)...

的列的值
RTS092
3ISUEX
ABCDEFGHIJ
9485028
数据输入/导入后,

在表中存储的值....

000000000RTS092
0000000003ISUEX
00000ABCDEFGHIJ
000000009485028

3 个答案:

答案 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值以及任一方的空白填充。

enter image description here

在它着陆之前修复它

正如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

由于我是展示我作品的粉丝,以下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))