简体   繁体   English

SQL Server 2008-CAST到nvarchar无法正常工作

[英]SQL Server 2008 - CAST to nvarchar not working

I have the following SQL statement as part of a trigger that is not working and cant figure out why: 我将以下SQL语句作为无法工作的触发器的一部分,无法弄清原因:

DECLARE @Orderid INT
DECLARE @CountOfOrderItems INT
DECLARE @EmployeeID INT
DECLARE @EmployeeName NVARCHAR

SELECT @Orderid = DELETED.id

SET @CountOfOrderItems = (select count(*) from OrderDetails where OrderID = @Orderid)

SET @EmployeeName = (SELECT Firstname + ' ' + Lastname from Employees where employees.id = 
                      (SELECT employeeid from Orders where Orders.id = @Orderid))

        INSERT INTO applicationlog (Sourceobject,Logtype,Message)
        VALUES ('Orders table',
                'Order deleted',
                'Order with ' + CAST(@CountOfOrderItems as varchar) + ' items deleted by '+ CAST(@EmployeeName as nvarchar))

The column datatypes for the applicationlog table are all nvarchar(255) for sourceobject and logtype and nvarchar(max) for message. applicationlog表的列数据类型对于Sourceobject和logtype都是nvarchar(255)对于message都是nvarchar(max)

The issue is, when I include the CAST(@EmployeeName as nvarchar) bit, nothing is entered in the message column, and it shows null. 问题是,当我包含CAST(@EmployeeName as nvarchar)位时,在消息列中未输入任何内容,并且显示为空。 Data is entered in the other two columns. 在其他两列中输入数据。 Casting the employeename as varchar also doesn't work. 将employeename varchar转换为varchar也不起作用。

When I remove the bit shown in bold above and use the following code, it works and the casting for the countoforderitems works. 当我删除上面以粗体显示的位并使用以下代码时,它可以工作,并且countoforderitems的强制转换也可以工作。

INSERT INTO applicationlog (Sourceobject,Logtype,Message)
VALUES ('Orders table',
        'Order deleted',
        'Order with ' + CAST(@CountOfOrderItems as varchar) + ' items deleted')

I have no idea why and would appreciate some help, as I need to log the user that is deleting the record. 我不知道为什么,希望得到一些帮助,因为我需要登录要删除记录的用户。

Thanks 谢谢

UPDATE UPDATE

Thanks to all that have responded. 感谢所有的回应。 I declared employeename as a VARCHAR(255) and edited the insert statement to 我将employeename声明为VARCHAR(255) ,并将insert语句编辑为

        INSERT INTO applicationlog (Sourceobject,Logtype,Message)
    values ('Orders table','Order deleted','Order with ' + CAST(@CountOfOrderItems as varchar(255)) + ' items deleted by ' + coalesce(@EmployeeName,''))

and now all information is there except the @Employeename which i think is returning an empty string, even though the employee exists in the table.So in the last column i now have "3 items deleted by " 现在所有的信息都在那里,除了@Employeename我认为它返回一个空字符串,即使该雇员存在于表中。所以在最后一栏中,我现在有“ 3个项目被删除”

Which is better than the null before, but why is the @Employeename blank? 哪个比以前的null好,但是@Employeename为什么为空白?

You are using nvarchar (or varchar or nchar or char ) without a length in at least three places. 您使用的nvarchar (或varcharncharchar )在至少三个地方没有长度。 Do not do this. 不要这样做。 The default length varies by context. 默认长度因上下文而异。 So: 所以:

DECLARE @EmployeeName NVARCHAR

Is really: 是真的:

DECLARE @EmployeeName NVARCHAR(1)

And

CAST(@CountOfOrderItems as varchar)

is really: 是真的:

CAST(@CountOfOrderItems as varchar(30))

(Okay, this is probably ok). (好的,这可能还可以)。

So, be explicit about the lengths. 因此,要明确长度。 You do not need to cast @EmployeeName for the string concatenation. 您不需要将@EmployeeName为字符串连接。 And, you do not need to use set because you can set the value of a variable in a select statement: 而且,您不需要使用set因为您可以在select语句中设置变量的值:

DECLARE @Orderid INT;
DECLARE @CountOfOrderItems INT;
DECLARE @EmployeeID INT;
DECLARE @EmployeeName NVARCHAR(255);

SELECT @Orderid = DELETED.id;  -- This looks strange.  I think you are missing a `from` clause

select  @CountOfOrderItems = count(*)
from OrderDetails
where OrderID = @Orderid);

SELECT @EmployeeName = Firstname + ' ' + Lastname
from Employees
where employees.id = (SELECT employeeid from Orders where Orders.id = @Orderid));

INSERT INTO applicationlog (Sourceobject, Logtype, Message)
    VALUES ('Orders table',
            'Order deleted',
            'Order with ' + CAST(@CountOfOrderItems as varchar(8000)) + ' items deleted by '+ @EmployeeName ;

Or, I would just dispense with all the intermediate stuff and do: 或者,我只是省去了所有中间步骤,然后做:

INSERT INTO applicationlog (Sourceobject, Logtype, Message)
    SELECT 'Orders table', 'Order deleted',
           replace(replace('Order with @n items deleted by @by',
                           '@n', count(od.orderid)
                          ), '@by', e.Firstname + ' ' + e.Lastname
                  )
    FROM deleted d JOIN
         orders o
         on d.id = o.orderId JOIN
         employees e
         on o.employeeid = e.employeeid LEFT JOIN
         orderdetails od
         on od.orderid = o.orderid;

I think a single query better shows the intention of what you are doing and you don't need to issue a bunch of queries and assign variables. 我认为单个查询可以更好地表明您正在执行的操作的意图,并且您无需发出一堆查询并分配变量。

It looks like you're mixing datatypes here. 看起来您在这里混用数据类型。 If you want it to be nvarchar then it all needs to be Nvarchar. 如果您希望它为nvarchar,则所有内容都必须为Nvarchar。 You should also specify the lengths you want like so: 您还应该指定所需的长度,如下所示:

VALUES ('Orders table',
                'Order deleted',
                N'Order with ' + CAST(@CountOfOrderItems as Nvarchar(10)) + N' items deleted by '+ CAST(@EmployeeName as nvarchar(10)))

This all being said I don't know why you are casting @EmployeeName as an Nvarchar when you've already declared it as Nvarchar, it seems a redundant process. 所有人都在说,我不知道为什么在已经将@EmployeeName声明为Nvarchar的情况下将@EmployeeName转换为Nvarchar,这似乎是一个多余的过程。

If your @EmployeeName is null it will also show null for the whole string, to get around this you can use the following statement at the top of you query: 如果您的@EmployeeName为null,则整个字符串也将显示为null,要解决此问题,可以在查询顶部使用以下语句:

SET CONCAT_NULL_YIELDS_NULL OFF

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM