2015-09-11 46 views
2

我有以下SQL语句不工作和触发的部分不能找出原因:的SQL Server 2008 - CAST为nvarchar不工作

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表中的列数据类型都nvarchar(255)用于sourceobject和logtype并且nvarchar(max)用于消息。

问题是,当我包含CAST(@EmployeeName as nvarchar)位时,消息列中没有输入任何内容,并且它显示为空。数据输入到另外两列。施放varchar雇佣人员也不起作用。

当我删除上面粗体显示的位并使用下面的代码时,它可以工作,并为countoforderitems投射。

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

我不知道为什么和希望得到一些帮助,因为我需要登录被删除记录的用户。

感谢

UPDATE

感谢社会各界反响热烈。我宣布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项删除了”

哪个比null好,但为什么@Employeename是空的?

+0

@EmployeeName在声明中已经是NVARCHAR,为什么要投它?如果它是空的,你的整个concat将是NULL,你必须做一些检查,并添加空字符串,如果它是NULL - COALESCE(@EmployeeName,'')...也像上面提到的你应该设置一个长度每次,当你声明它没有长度,默认为1 –

+4

您的触发器似乎被破坏 - “已删除”是一个表,可能包含0,1或*多*行。将它的值赋给一个标量变量,'SELECT @Orderid = DELETED.id'是有缺陷的(如果这样的话甚至可以工作 - 我还以为你还需要一个用于该查询的'FROM'子句)。 –

+0

达米恩 - 我的理解是,当一条记录即一行被删除时,触发器会运行?如果我错了,请纠正我。是的SELECT @orderid确实返回一个值,语法看起来很奇怪,但在这里有其他触发器使用它,并工作fine.cheers – Nick

回答

0

它看起来像你在这里混合数据类型。如果你想要它是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,它也将显示空整个字符串,来解决这个问题,你可以在你的顶部使用下面的语句查询:

SET CONCAT_NULL_YIELDS_NULL OFF 
2

您正在使用nvarchar(或varcharncharchar)在至少三个地方没有长度。 不要这样做。默认长度因上下文而异。所以:

DECLARE @EmployeeName NVARCHAR 

是真的:

DECLARE @EmployeeName NVARCHAR(1) 

而且

CAST(@CountOfOrderItems as varchar) 

是真的:

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; 

我认为单个查询可以更好地显示您正在执行的操作的意图,而且您不需要发出一堆查询并分配变量。

+0

感谢您的回应戈登。我尝试了您的单一查询解决方案,但出现错误。我编辑了一些表名,但仍然有2个错误,都与名字和姓氏有关 - 错误是“Column'employees.Lastname'在选择列表中无效,因为它不包含在聚合函数或GROUP BY条款“。 – Nick

+0

我编辑该位FROM删除ðJOIN上d.id = o.Id 级O JOIN 员工上o.employeeid = e.id LEFTË JOIN ORDERDETAILS上od.orderid = o.id OD – Nick

相关问题