Как конвертировать числовые значения в nvarchar в SQL Server? - PullRequest
0 голосов
/ 06 мая 2019

Рассмотрим следующую таблицу. Я использую триггер, чтобы добавить в таблицу. В столбце преобразования числа в строку происходит сбой.

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

Ответы [ 3 ]

5 голосов
/ 06 мая 2019

У вас есть несколько проблем:

@@IDENTITY - это системная функция, содержащая последнее значение идентификатора, которое генерируется, когда INSERT,SELECT INTO или BULK 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;

Посмотрите, как это работает .

Смотрите также этоартикул Properly Persisted Computed Columns по Paul White.

2 голосов
/ 28 мая 2019

SELECT CAST([PictureId] AS NVARCHAR(4)) From Category

2 голосов
/ 06 мая 2019

Попробуйте это

SELECT CONVERT(NVARCHAR(255), @AgentCode)
...