我正在尝试使用存储过程进行插入,但是我得到了
将数据类型nvarchar转换为数字时出错
我正在使用SQL Server / Azure Data Studio。
这是我正在使用的桌子
CREATE TABLE Clinics
(
ClinicID INT PRIMARY KEY IDENTITY(1, 1),
ClinicName NVARCHAR(100) NOT NULL UNIQUE,
ClinicPhoneNumber NVARCHAR(100) NOT NULL,
ClinicAddress NVARCHAR(100) NOT NULL,
ClinicCity NVARCHAR(100) NOT NULL,
ClinicState NVARCHAR(100) NOT NULL,
ClinicZipCode NVARCHAR(10),
CONSTRAINT CHK_ClinicPhone
CHECK(ClinicPhoneNumber = FORMAT(CAST(ClinicPhoneNumber AS NUMERIC), '###-###-####')),
CONSTRAINT CHK_ClinicZip
CHECK(ClinicZipCode = FORMAT(CAST(ClinicZipCode AS NUMERIC), '#####')
OR ClinicZipCode = FORMAT(CAST(ClinicZipCode AS NUMERIC), '#####-####'))
);
GO
这是我的程序代码
CREATE PROCEDURE pInsertClinic
(@ClinicName NVARCHAR(100),
@ClinicPhoneNumber NVARCHAR(100),
@ClinicAddress NVARCHAR(100),
@ClinicCity NVARCHAR(100),
@ClinicState NVARCHAR(100),
@ClinicZipCode NVARCHAR(10))
AS
BEGIN
DECLARE @RC int = 0;
BEGIN TRY
BEGIN TRANSACTION
SET NOCOUNT ON
INSERT INTO Clinics (ClinicName, ClinicPhoneNumber, ClinicAddress,
ClinicCity, ClinicState, ClinicZipCode)
VALUES (@ClinicName, @ClinicPhoneNumber, @ClinicAddress,
@ClinicCity, @ClinicState, @ClinicZipCode)
COMMIT TRANSACTION
SET @RC = +1
END TRY
BEGIN CATCH
IF (@@Trancount > 0)
ROLLBACK TRANSACTION
PRINT Error_Message()
SET @RC = -1
END CATCH
RETURN @RC;
END
GO
这是我的执行代码:
BEGIN
EXEC pInsertClinic
@ClinicName = 'General Clinic',
@ClinicPhoneNumber = '943-309-3094',
@ClinicAddress = '9876 fourth st',
@ClinicCity = 'Seattle',
@ClinicState = 'WA',
@ClinicZipCode = '98118';
SELECT * FROM vClinics;
END
GO
姓名,电话和地址信息应与执行程序中的相同。诊所ID应该自动分配为整数
答案 0 :(得分:0)
表结构应该是这样的。
CREATE TABLE Clinics
(
ClinicID INT PRIMARY KEY IDENTITY(1, 1),
ClinicName NVARCHAR(100) NOT NULL UNIQUE,
ClinicPhoneNumber NVARCHAR(100) NOT NULL,
ClinicAddress NVARCHAR(100) NOT NULL,
ClinicCity NVARCHAR(100) NOT NULL,
ClinicState NVARCHAR(100) NOT NULL,
ClinicZipCode NVARCHAR(10),
CONSTRAINT CHK_ClinicPhone
CHECK(ClinicPhoneNumber = FORMAT(CAST(REPLACE(ClinicPhoneNumber,'-','') AS NUMERIC), '###-###-####')),
CONSTRAINT CHK_ClinicZip
CHECK(ClinicZipCode = FORMAT(CAST(ClinicZipCode AS NUMERIC), '#####')
OR ClinicZipCode = FORMAT(CAST(ClinicZipCode AS NUMERIC), '#####-####'))
);
GO
答案 1 :(得分:0)
重新开始。这次,在执行其他任何操作之前,请先考虑一下数据类型。问题:
对此以及您可能遇到的任何其他问题(或可能遇到的问题),您的第一个响应应该是搜索互联网。强制执行有关字符串内容的规则是一个常见问题,您可以通过非常简单的搜索找到许多示例。在这种情况下,您可以简单地搜索“ stackoverflow限制电话号码”以查找过去的讨论。因此,依靠one of those,我们可以使用类似以下的内容。
set nocount on;
if object_id('tempdb..#Clinics') is not null
drop table #Clinics;
go
CREATE TABLE #Clinics
(
ID INT PRIMARY KEY IDENTITY(1, 1),
Name NVARCHAR(100) NOT NULL UNIQUE,
PhoneNumber VARCHAR(12) NOT NULL,
Address NVARCHAR(100) NOT NULL,
City NVARCHAR(100) NOT NULL,
State CHAR(2) NOT NULL,
ZipCode VARCHAR(10) not null
);
GO
insert #Clinics (Name, PhoneNumber, Address, City, State, ZipCode)
values ('Text Clinic', '111-2222', '123 Main Street', 'Seattle', 'WA', '11111');
select * from #Clinics;
go
alter table #Clinics add constraint chk_phone check (PhoneNumber like '[0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]')
go
insert #Clinics (Name, PhoneNumber, Address, City, State, ZipCode)
values ('Bad number', '1112222', '987 Main Street', 'Seattle', 'WA', '11111'); -- error
insert #Clinics (Name, PhoneNumber, Address, City, State, ZipCode)
values ('Good Clinic', '123-4444', '987 Main Street', 'Seattle', 'WA', '11111');
insert #Clinics (Name, PhoneNumber, Address, City, State, ZipCode)
values ('Short Number', '123-444', '987 Main Street', 'Seattle', 'WA', '11111'); -- error
insert #Clinics (Name, PhoneNumber, Address, City, State, ZipCode)
values ('Short Exchange', '13-4445', '987 Main Street', 'Seattle', 'WA', '11111'); --error
insert #Clinics (Name, PhoneNumber, Address, City, State, ZipCode)
values ('Bad Separator', '213+4445', '987 Main Street', 'Seattle', 'WA', '11111'); --error
insert #Clinics (Name, PhoneNumber, Address, City, State, ZipCode)
values ('Letters', '213-A445', '987 Main Street', 'Seattle', 'WA', '11111'); --error
select * from #Clinics;
这显示了方法-您需要扩展它才能完整地实施。但是在您这样做之前,我必须质疑原因。通常可以在GUI中更好地实现这种功能。通常,人们会使用一个会自动强制执行此操作的掩码。应用程序还可以为基本输入错误提供更好的指导和错误处理-丑陋且难以读取的本机sql server错误几乎不友好。
您还应该仔细考虑重新考虑某种格式对存储的强制使用。有些人更喜欢将电话号码视为(999)123-4567。我已经看到了许多使用句点而不是破折号的示例。您在此作出的承诺以后将很难更改。
最后一条评论。您不能一次完成所有操作。暂时不使用该过程。定义表并使用包含好数据和坏数据的DML语句验证约束是否正常工作。一旦可行,您就可以添加存储过程的复杂性。一旦可行,就可以将过程的使用合并到应用程序中。该方法适用于任何类型的代码开发-您不能在未经测试和验证的基础上构建。