Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL Server 2008-强制转换到nvarchar不工作_Sql_Sql Server_Triggers - Fatal编程技术网

SQL Server 2008-强制转换到nvarchar不工作

SQL Server 2008-强制转换到nvarchar不工作,sql,sql-server,triggers,Sql,Sql Server,Triggers,我将以下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 =

我将以下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))
applicationlog表的列数据类型对于sourceobject和logtype都是
nvarchar(255)
,对于message则是
nvarchar(max)

问题是,当我包含
强制转换(@EmployeeName as nvarchar)
位时,消息列中没有输入任何内容,它显示为null。在其他两列中输入数据。将employeename强制转换为
varchar
也不起作用

当我删除上面粗体显示的位并使用下面的代码时,它工作了,countoforderitems的转换也工作了

INSERT INTO applicationlog (Sourceobject,Logtype,Message)
VALUES ('Orders table',
        'Order deleted',
        'Order with ' + CAST(@CountOfOrderItems as varchar) + ' items deleted')
我不知道为什么,希望能得到一些帮助,因为我需要记录删除记录的用户

谢谢

更新

感谢所有的回应。我将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,''))
现在,除了@Employeename之外,所有信息都在那里,我认为它返回的是一个空字符串,即使表中存在雇员。因此,在最后一列中,我现在有“3个项目被”


这比以前的空值要好,但为什么@Employeename为空?

看起来您在混合数据类型。如果你想让它成为nvarchar,那么它就必须是nvarchar。还应指定所需的长度,如下所示:

VALUES ('Orders table',
                'Order deleted',
                N'Order with ' + CAST(@CountOfOrderItems as Nvarchar(10)) + N' items deleted by '+ CAST(@EmployeeName as nvarchar(10)))
说了这么多,我不知道你为什么要把@EmployeeName选为Nvarchar,而你已经宣布它为Nvarchar,这似乎是一个多余的过程

如果@EmployeeName为null,则整个字符串也将显示null,要避免此问题,可以在查询顶部使用以下语句:

SET CONCAT_NULL_YIELDS_NULL OFF

您使用的
nvarchar
(或
varchar
nchar
char
)至少三处没有长度。不要这样做。默认长度因上下文而异。因此:

DECLARE @EmployeeName NVARCHAR
事实上:

DECLARE @EmployeeName NVARCHAR(1)

事实上:

CAST(@CountOfOrderItems as varchar(30))
(好的,这可能没问题)

所以,要明确长度。字符串串联不需要强制转换
@EmployeeName
。而且,您不需要使用
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 ;
或者,我会省去所有的中间材料,然后做:

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;

我认为一个查询更好地显示了您正在做的事情的意图,您不需要发出一堆查询和分配变量。

@EmployeeName在声明中已经是NVARCHAR了,为什么要强制执行它?如果它为null,则整个concat都将为null,如果它为null,则必须进行一些检查并添加空字符串-COALESCE(@EmployeeName,,)。。。同样,正如前面提到的,每次您都应该设置一个长度,当您声明它不带长度时,默认值是1您的触发器似乎已断开-
deleted
是一个可能包含0、1或多行的表。将值从它赋给标量变量,
SELECT@Orderid=DELETED.id
是有缺陷的(如果这样做有效的话-我还以为您仍然需要一个
from
子句来进行查询)。Damien-我的理解是,当一条记录(即一行)被删除时,触发器会运行吗?如果我错了,请纠正我。是的,SELECT@orderid确实返回了一个值,语法看起来很奇怪,但是这里还有其他触发器使用它并且工作正常。谢谢你的回答。我尝试了您的单一查询解决方案,但出现了一个错误。我在上面编辑了一些表名,但仍然有两个错误,都与firstname和lastname有关-错误是“列'employees.lastname'在选择列表中无效,因为它不包含在聚合函数或GROUP BY子句中。”我从已删除的d加入订单o上编辑了此位。d.id=o.id加入员工e上o.employeeid=e.id左加入订单详细信息od.orderid=o.id
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;