SQL Server:如何在包含数字的字符中大写字母

时间:2017-03-08 17:09:36

标签: sql-server stored-procedures triggers char uppercase

我正在努力解决这个问题。我似乎无法得到一个邮政编码,总是看起来像这种格式1234AB。

pc CHAR(6) NOT NULL  
CONSTRAINT CK_pc CHECK( pc LIKE '[1-9][0-9][0-9][0-9][A-Z][A-Z]')

这可以完成正确的数字和字母,但它不会将最后两个字母大写。

例如: 如果我输入1234aB,它将完全存储在数据库中,而我希望它像1234AB一样存储。

我想我需要在这里使用触发器或程序,但我不确定如何。

提前致谢!

4 个答案:

答案 0 :(得分:2)

您可以使用排序规则来使此约束工作,但它有点时髦。您必须在约束中包含排序规则,但您还必须检查是否相等,因为默认排序规则将被忽略。

create table CapTest
(
    pc char(6) collate SQL_Latin1_General_CP1_CS_AS not null
)

alter table CapTest
add constraint CK_pc  check(pc LIKE '[1-9][0-9][0-9][0-9][A-Z][A-Z]' AND pc = upper(pc)) 


insert CapTest
select '1234AB' --this will work fine

insert CapTest
select '1234Ab' --this will fail the constraint

select * from CapTest

drop table CapTest

- 编辑 -

从现在开始,您似乎想要实际更改插入的值,您需要使用而不是使用触发器而不是约束。以下是使用而不是触发器来执行此操作的方法。

create table CapTest
(
    pc char(6)  not null
)

alter table CapTest
add constraint CK_pc  check(pc LIKE '[1-9][0-9][0-9][0-9][A-Z][A-Z]') 

go

create trigger tr_CapTestInsert on CapTest instead of insert as
begin
    insert CapTest(pc)
    select UPPER(i.pc)
    from inserted i
end

GO

insert CapTest
select '1234AB' union all
select '1234Ab' union all
select '1234aB' union all
select '1234ab' 

select * from CapTest

drop table CapTest

答案 1 :(得分:0)

您必须使用区分大小写的排序规则。例如,假设列pc CHAR(6) NOT NULL的排序规则为SQL_Latin1_General_CP1_CI_AS

SELECT  col.COLLATION_NAME
FROM    INFORMATION_SCHEMA.COLUMNS col
WHERE   col.TABLE_SCHEMA = 'dbo'
AND     col.TABLE_NAME = 'TableA'
AND     col.COLUMN_NAME = 'pc'
-- returns SQL_Latin1_General_CP1_CI_AS

我会使用以下CHECK约束以及相同排序规则的区分大小写版本(在本例中为SQL_Latin1_General_CP1_CS_AS):

CREATE TABLE dbo.TableA(
    pc CHAR(6) NOT NULL,
    CONSTRAINT CK_pc CHECK( pc COLLATE SQL_Latin1_General_CP1_CS_AS LIKE N'[1-9][0-9][0-9][0-9][A-Z][A-Z]' )
)
GO

ALTER TABLE dbo.TableA
DROP CONSTRAINT CK_pc
GO
ALTER TABLE dbo.TableA
ADD CONSTRAINT CK_pc CHECK( pc COLLATE SQL_Latin1_General_CP1_CS_AS LIKE N'[1-9][0-9][0-9][0-9][A-Z][A-Z]' )
GO

ALTER TABLE dbo.TableA
DROP CONSTRAINT CK_pc
GO
ALTER TABLE dbo.TableA
ADD CONSTRAINT CK_pc CHECK( pc COLLATE Latin1_General_CS_AS LIKE '[1-9][0-9][0-9][0-9][A-Z][A-Z]' )
GO

然后

INSERT dbo.TableA VALUES ('1234aa')
/*
Msg 547, Level 16, State 0, Line 6
The INSERT statement conflicted with the CHECK constraint "CK_pc15". The conflict occurred in database "Test", table "dbo.Table15", column 'pc'.
The statement has been terminated.
*/
GO

INSERT dbo.TableA VALUES ('1234AA')
/*
(1 row(s) affected)
*/

注意:我们可以看到,我们没有(在这种情况下)更改列的COLLATION。

答案 2 :(得分:0)

如果您可以访问INSERT所在的代码,请使用UPPER,如下所示:

INSERT INTO PostalCode (pc) VALUES (UPPER('1234ab'))

如果您无法访问INSERT命令所在的代码,则可以删除约束并使用触发器(CREATE TRIGGER)来确保存储的数据始终为大写:

CREATE TABLE PostalCode(
    pc CHAR(6) NOT NULL
)

CREATE TRIGGER PostalCode_INSERT_UPDATE
       ON PostalCode
AFTER INSERT, UPDATE
AS
BEGIN
       SET NOCOUNT ON;

       UPDATE PostalCode
        SET pc = UPPER(pc)
        WHERE pc in (SELECT INSERTED.pc FROM INSERTED)

END

INSERT INTO PostalCode
       VALUES('1234ab')

SELECT * FROM PostalCode   

pc
1234AB    

UPDATE PostalCode SET pc = '1234ab' WHERE pc = '1234AB'

SELECT * FROM PostalCode       

pc
1234AB

答案 3 :(得分:-1)

通常,您不会在触发器中执行此操作。您需要创建一个约束(如前面的答案),以便进入的数据始终有效。然后,您可以在代码中创建一个函数(或存储过程),以返回格式正确的邮政编码。您的案例非常简单,您可以像其他人建议的那样使用内置的sql函数upper()。如果您有更复杂的格式,您可以创建自己的格式。

create function fFormatPostalCode2 
(
    @Code char(6)
)
returns char(6)
as
begin
    return upper(@Code)  -- any other formating here
end

declare @r char(6)
set @r = dbo.fFormatPostalCode('1232aB')
select @r