我正在努力解决这个问题。我似乎无法得到一个邮政编码,总是看起来像这种格式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一样存储。
我想我需要在这里使用触发器或程序,但我不确定如何。
提前致谢!
答案 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