簡體   English   中英

如何在 SQL Server 中將數字轉換為 nvarchar?

[英]How to convert numeric to nvarchar in SQL Server?

考慮下表。 我使用觸發器添加到表中。 在將數字轉換為字符串的列中,它失敗了。

CREATE TABLE [dbo].[tblAIAgent]
(
    [AgentCode] [NVARCHAR](10) NOT NULL,
    [NationalCode] [BIGINT] NOT NULL 
         CONSTRAINT [DF_tblAIAgent_NationalCode]  DEFAULT ((0)),
    [FirstName] [NVARCHAR](50) NOT NULL 
         CONSTRAINT [DF_tblAIAgent_Name] DEFAULT (''),
    [LastName] [NVARCHAR](50) NOT NULL 
         CONSTRAINT [DF_tblAIAgent_Family] DEFAULT (''),
    [IsActive] [BIT] NOT NULL 
         CONSTRAINT [DF_tblAIAgent_Active] DEFAULT ((1)),
    [Counter] [INT] IDENTITY(1,1) NOT NULL,

    CONSTRAINT [PK_tblAIAgent] 
        PRIMARY KEY CLUSTERED 
)

ALTER TRIGGER [dbo].[AgentInsert] 
ON [dbo].[tblAIAgent]
INSTEAD OF INSERT
AS
BEGIN
    DECLARE @AgentCode NVARCHAR(10)
    DECLARE @NationalCode BIGINT
    DECLARE @FirstName NVARCHAR(50)
    DECLARE @LastName NVARCHAR(50)
    DECLARE @IsActive BIT
    DECLARE @CounterIs INT

    SET @CounterIs = @@IDENTITY

    SELECT
        @AgentCode = AgentCode,
        @NationalCode = NationalCode,
        @FirstName = FirstName,
        @LastName = LastName,
        @IsActive = IsActive 
    FROM inserted

    INSERT INTO tblAIAgent (NationalCode, FirstName, LastName, IsActive, AgentCode)
    VALUES (@NationalCode, @FirstName, @LastName, @IsActive, 'Agent_' + CAST(@CounterIs AS NVARCHAR(4))) 
END

你在這里有幾個問題:

@@IDENTITY是一個系統函數,包含在INSERTSELECT INTOBULK COPY語句完成時生成的最后一個標識值。 如果該語句不影響具有標識列的任何表, @@IDENTITY返回NULL 如果插入多行,生成多個標識值, @@IDENTITY返回生成的最后一個標識值。

在您的情況下,您有一個INSTEAD OF INSERT觸發器,因此沒有INSERT

下面的查詢是完全錯誤的,會給出錯誤的結果,只有在插入一行時它才能按預期工作,如果有超過 1 行,那么這些變量將只保存一行的值,而您將丟失其他值其他行,導致偽INSERTED可能包含 1 行或更多行

select @AgentCode=AgentCode,
       @NationalCode=NationalCode,
       @FirstName=FirstName,
       @LastName=LastName,
       @IsActive=IsActive 
from inserted

現在,查看您的表,您已經有一個IDENTITY列,因此您根本不需要TRIGGER ,您只需創建一個計算列即可

CREATE TABLE [dbo].[tblAIAgent](
    [AgentCode] AS 'Agent_' + CAST([Counter] AS VARCHAR(10)),
    [NationalCode] [bigint] NOT NULL 
    CONSTRAINT [DF_tblAIAgent_NationalCode]  DEFAULT ((0)),
    [FirstName] [nvarchar](50) NOT NULL 
    CONSTRAINT [DF_tblAIAgent_Name]  DEFAULT (''),
    [LastName] [nvarchar](50) NOT NULL 
    CONSTRAINT [DF_tblAIAgent_Family]  DEFAULT (''),
    [IsActive] [bit] NOT NULL 
    CONSTRAINT [DF_tblAIAgent_Active]  DEFAULT ((1)),
    [Counter] [int] IDENTITY(1,1) NOT NULL,
    CONSTRAINT [PK_tblAIAgent] PRIMARY KEY ([Counter])
    );

更新:

根據您的評論“無法再選擇計算列作為 PK。我希望將此列作為 FK 放置在其他相關表中。我編寫了觸發器來獲取列值而不是計算列,以便我可以選擇該列作為主鍵" 您正在嘗試將其設為PRIMARY KEY以便您可以這樣做

CREATE TABLE T(
  Counter INT IDENTITY(1,1) NOT NULL,
  OtherCol INT,
  Computed AS CONCAT('Agent_', CAST(Counter AS VARCHAR(10))) PERSISTED,
  CONSTRAINT PKT PRIMARY KEY(Computed)
);

CREATE TABLE TT(
  ReferenceComputedColumn VARCHAR(16) NOT NULL,
  OtherColumn INT,
  CONSTRAINT FK_ReferencedComputedColumn 
      FOREIGN KEY(ReferenceComputedColumn) 
      REFERENCES T(Computed)
)

INSERT INTO T(OtherCol) VALUES
(1), (2), (3);

INSERT INTO TT(ReferenceComputedColumn, OtherColumn) VALUES
('Agent_1', 10),
('Agent_3', 20);

SELECT *
FROM T LEFT JOIN TT 
ON T.Computed = TT.ReferenceComputedColumn;

看看它是如何工作的

另請參閱Paul White撰寫的這篇文章Properly Persisted Computed Columns

嘗試這個

SELECT CONVERT(NVARCHAR(255), @AgentCode)
SELECT CAST([PictureId] AS NVARCHAR(4)) From Category

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM