作为一个菜鸟,我真的在与此作斗争。
我有一张表如下
SELECT [AuditFieldID]
,[CompanyRuleID]
,[CompanyRule]
,[VipUserName]
,[EffectiveDate]
,[FieldName]
,[SourceCode]
,[Action]
,[AccountNoOldValue]
,[AccountNoNewValue]
,[AccountTypeOldValue]
,[AccountTypeNewValue]
,[BankOldValue]
,[BankNewValue]
,[BranchOldValue]
,[BranchNewValue]
,[AccountHolderOldValue]
,[AccountHolderNewValue]
FROM [SageStaging].[MASSMART].[AuditCondensed]
每个员工的表格中有5行。前5个字段包含相同的数据,然后fieldname字段包含不同的记录类型。
所以你会有
Auditfieldid = 111111
CompanyRuleID = 12
CompanyRule = Walmart
VipUsername = john.doe
EffectiveDate = date()
Fieldname = 'Account Holder Name'
SourceCode = 1234 - John Doe
Action = I
AccountNoOldValue = NULL
AccountNoNewValue = NULL
AccountTypeOldValue = NULL
AccountTypeNewValue = NULL
BankOldValue = NULL
BankNewValue = NULL
BranchOldValue = NULL
BranchNewValue = NULL
AccountHoldOldValue = ''
AcccountHolderNewValue = 'John Doe'
有五种字段名称类型:
FieldName = 'Account Holder Name'
FieldName = 'Account Number'
FieldName = 'Account Type'
FieldName = 'Bank'
FieldName = 'Bank Branch'
如果FieldName为='帐户持有人',则记录将包含AccountHoldOldValue和AccountHoldNewValue中的值
如果FieldName为='帐号',则记录将包含AccountNoOldValue和AccountNoNewValue中的值
等等。总而言之,您有5个不同fieldname类型的记录,并且在行中根据fieldname类型填充了相应的值字段。
我需要发送一封包含这些值的电子邮件。一封电子邮件创建了以下内容:
SET @MailSubject = 'Banking Details Change Notification for Employee' + ' ' + @SOURCECODE
SET @MessageBody = '<html>
<head>
<meta content="text/html; charset=ISO-8859-1"
http-equiv="content-type">
<title></title>
</head>
<body>
<br>
The following bank details have been changed:
<br>
<br>
Date Changed: ' + @EFFECTIVEDATE + '<br>' +
' Company: ' + @COMPANYRULE + '<br>' +
' Username: ' + @VIPUSERNAME + '<br>' +
' Employee Details: ' + @SOURCECODE + '<br>' +
' Action: ' + @ACTION + '<br>' +
' Account Holder: ' + ' Old Value: ' + @ACCOUNTHOLDEROLDVALUE + ' New Value: ' + @ACCOUNTHOLDERNEWVALUE + '<br>' +
' Account Number: ' + ' Old Value: ' + @ACCOUNTNOOLDVALUE + ' New Value: ' + @ACCOUNTNONEWVALUE + '<br>' +
' Account Type: ' + ' Old Value: ' + @ACCOUNTTYPEOLDVALUE + ' New Value: ' + @ACCOUNTTYPENEWVALUE + '<br>' +
' Bank: ' + ' Old Value: ' + @BANKOLDVALUE + ' New Value: ' + @BANKNEWVALUE + '<br>' +
' Bank Branch: ' + ' Old Value: ' + @BRANCHOLDVALUE + ' New Value: ' + @BRANCHNEWVALUE + '<br>' +
'<br>
<br>
<b>
Please do not respond to this email. If you have any questions regarding this email, please
contact your payroll administrator <br>
<br>
<br>
</body>'
我似乎无法弄清楚如何只发送一封包含所有必要字段的电子邮件。
我似乎在所有字段中都收到五封空白的电子邮件,只记录了记录的前四个字段。
答案 0 :(得分:0)
此查询应该为每封电子邮件提供一条记录。
laravel 5.4
您获得了令人震惊的数据库设计;我发现很难,我并不感到惊讶。该名称表明它是精简数据。它不是。这实际上是一个非常浪费的结构。
我担心每个员工有5行的断言。如果有些人没有全部5行,则必须进行外连接。如果是这种情况,您将需要为每位员工提供一种可靠的记录类型。
答案 1 :(得分:0)
从个人经验来看,每当你构建一个这样的字符串,将一堆字符串连接在一起时,你应该将每个变量包装在一个ISNULL检查中。一个空变量,整个字符串将为null。
您应该在功能中隔离用于创建电子邮件正文的逻辑。以下是一个完整的示例,其中包含用于测试的示例DDL和DML语句:
CREATE TABLE AuditCondensed (
[AuditFieldID] INT
,[CompanyRuleID] INT
,[CompanyRule] VARCHAR(10)
,[VipUserName] VARCHAR(10)
,[EffectiveDate] DATE
,[FieldName] VARCHAR(25)
,[SourceCode] VARCHAR(25)
,[Action] CHAR(1)
,[AccountNoOldValue] VARCHAR(25)
,[AccountNoNewValue] VARCHAR(25)
,[AccountTypeOldValue] VARCHAR(25)
,[AccountTypeNewValue] VARCHAR(25)
,[BankOldValue] VARCHAR(25)
,[BankNewValue] VARCHAR(25)
,[BranchOldValue] VARCHAR(25)
,[BranchNewValue] VARCHAR(25)
,[AccountHolderOldValue] VARCHAR(25)
,[AccountHolderNewValue] VARCHAR(25))
INSERT INTO AuditCondensed VALUES (111111, 12, 'Walmart', 'john.doe', GETDATE(), 'Account Number', '1234 - John Doe', 'I', '12345', '1234567-123', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL)
INSERT INTO AuditCondensed VALUES (111111, 12, 'Walmart', 'john.doe', GETDATE(), 'Account Type', '1234 - John Doe', 'I', NULL, NULL, NULL, 'Savings', NULL, NULL, NULL, NULL, NULL, NULL)
INSERT INTO AuditCondensed VALUES (111111, 12, 'Walmart', 'john.doe', GETDATE(), 'Bank', '1234 - John Doe', 'I', NULL, NULL, NULL, NULL, 'Old Bank', 'New Bank', NULL, NULL, NULL, NULL)
INSERT INTO AuditCondensed VALUES (111111, 12, 'Walmart', 'john.doe', GETDATE(), 'Branch', '1234 - John Doe', 'I', NULL, NULL, NULL, NULL, NULL, NULL, 'Branch 1', 'Branch 2', NULL, NULL)
INSERT INTO AuditCondensed VALUES (111111, 12, 'Walmart', 'john.doe', GETDATE(), 'Account Holder', '1234 - John Doe', 'I', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '', 'John Doe')
CREATE FUNCTION dbo.fn_create_email_body(@SourceCode VARCHAR(25)) RETURNS NVARCHAR(MAX)
AS
BEGIN
DECLARE @MailSubject NVARCHAR(200) = ''
DECLARE @MessageBody NVARCHAR(MAX) = ''
DECLARE @EFFECTIVEDATE DATE
DECLARE @COMPANYRULE VARCHAR(10)
DECLARE @VIPUSERNAME VARCHAR(10)
DECLARE @ACTION CHAR(1)
DECLARE @ACCOUNTHOLDEROLDVALUE VARCHAR(25)
DECLARE @ACCOUNTHOLDERNEWVALUE VARCHAR(25)
DECLARE @ACCOUNTNOOLDVALUE VARCHAR(25)
DECLARE @ACCOUNTNONEWVALUE VARCHAR(25)
DECLARE @ACCOUNTTYPEOLDVALUE VARCHAR(25)
DECLARE @ACCOUNTTYPENEWVALUE VARCHAR(25)
DECLARE @BANKOLDVALUE VARCHAR(25)
DECLARE @BANKNEWVALUE VARCHAR(25)
DECLARE @BRANCHOLDVALUE VARCHAR(25)
DECLARE @BRANCHNEWVALUE VARCHAR(25)
SELECT TOP 1 @EFFECTIVEDATE = EffectiveDate, @COMPANYRULE = CompanyRule, @VIPUSERNAME = VipUserName, @ACTION = Action,
@ACCOUNTHOLDEROLDVALUE = (SELECT AccountHolderOldValue FROM AuditCondensed WHERE SourceCode = @SourceCode AND FieldName = 'Account Holder'),
@ACCOUNTHOLDERNEWVALUE = (SELECT AccountHolderNewValue FROM AuditCondensed WHERE SourceCode = @SourceCode AND FieldName = 'Account Holder'),
@ACCOUNTNOOLDVALUE = (SELECT AccountNoOldValue FROM AuditCondensed WHERE SourceCode = @SourceCode AND FieldName = 'Account Number'),
@ACCOUNTNONEWVALUE = (SELECT AccountNoNewValue FROM AuditCondensed WHERE SourceCode = @SourceCode AND FieldName = 'Account Number'),
@ACCOUNTTYPEOLDVALUE = (SELECT AccountTypeOldValue FROM AuditCondensed WHERE SourceCode = @SourceCode AND FieldName = 'Account Type'),
@ACCOUNTTYPENEWVALUE = (SELECT AccountTypeNewValue FROM AuditCondensed WHERE SourceCode = @SourceCode AND FieldName = 'Account Type'),
@BANKOLDVALUE = (SELECT BankOldValue FROM AuditCondensed WHERE SourceCode = @SourceCode AND FieldName = 'Bank'),
@BANKNEWVALUE = (SELECT BankNewValue FROM AuditCondensed WHERE SourceCode = @SourceCode AND FieldName = 'Bank'),
@BRANCHOLDVALUE = (SELECT BranchOldValue FROM AuditCondensed WHERE SourceCode = @SourceCode AND FieldName = 'Branch'),
@BRANCHNEWVALUE = (SELECT BranchNewValue FROM AuditCondensed WHERE SourceCode = @SourceCode AND FieldName = 'Branch')
FROM AuditCondensed
WHERE SourceCode = @SourceCode
SET @MessageBody = '<html>
<head>
<meta content="text/html; charset=ISO-8859-1"
http-equiv="content-type">
<title></title>
</head>
<body>
<br>
The following bank details have been changed:
<br>
<br>
Date Changed: ' + ISNULL(FORMAT(@EFFECTIVEDATE, 'M/d/yyyy'), '') + '<br>' +
' Company: ' + ISNULL(@COMPANYRULE, '') + '<br>' +
' Username: ' + ISNULL(@VIPUSERNAME, '') + '<br>' +
' Employee Details: ' + ISNULL(@SOURCECODE, '') + '<br>' +
' Action: ' + ISNULL(@ACTION, '') + '<br>' +
' Account Holder: ' + ' Old Value: ' + ISNULL(@ACCOUNTHOLDEROLDVALUE, '') + ' New Value: ' + ISNULL(@ACCOUNTHOLDERNEWVALUE, '') + '<br>' +
' Account Number: ' + ' Old Value: ' + ISNULL(@ACCOUNTNOOLDVALUE, '') + ' New Value: ' + ISNULL(@ACCOUNTNONEWVALUE, '') + '<br>' +
' Account Type: ' + ' Old Value: ' + ISNULL(@ACCOUNTTYPEOLDVALUE, '') + ' New Value: ' + ISNULL(@ACCOUNTTYPENEWVALUE, '') + '<br>' +
' Bank: ' + ' Old Value: ' + ISNULL(@BANKOLDVALUE, '') + ' New Value: ' + ISNULL(@BANKNEWVALUE, '') + '<br>' +
' Bank Branch: ' + ' Old Value: ' + ISNULL(@BRANCHOLDVALUE, '') + ' New Value: ' + ISNULL(@BRANCHNEWVALUE, '') + '<br>' +
'<br>
<br>
<b>
Please do not respond to this email. If you have any questions regarding this email, please
contact your payroll administrator <br>
<br>
<br>
</body>'
RETURN @MessageBody
END
GO
SELECT dbo.fn_create_email_body('1234 - John Doe')
请注意设置所有变量值的函数中的查询。它使用TOP来设置所有常量变量的值,使用子查询来有条件地设置依赖于FieldName的变量。如果使用此方法,则需要确保变量(和长度)的数据类型与数据库匹配。
答案 2 :(得分:0)
也许是另一种方法 dbFiddle
示例强>
-- Just creating a DUMMY dataset --
-----------------------------------
Declare @YourTable table (ID int,Active bit,First_Name varchar(50),Last_Name varchar(50),EMail varchar(50))
Insert into @YourTable values
(1,1,'John','Smith','johnsmith.@email.com'),
(2,0,'Jane','Doe','janedoe.@email.com')
-- Here we have our Pattern/Template --
---------------------------------------
Declare @Pattern varchar(max) = '
Dear [[First_Name]] [[Last_Name]]
Please confirm your email address <b>[[EMail]]</b>
Thank You
'
-- The actual query --
----------------------
Select A.ID
,Formatted = [dbo].[svf-Str-Tokenize]((Select A.* for XML Raw),@Pattern)
From @YourTable A
<强>返回强>
ID Formated
1 Dear John Smith
Please confirm your email address <b>johnsmith.@email.com</b>
Thank You
2 Dear Jane Doe
Please confirm your email address <b>janedoe.@email.com</b>
Thank You
感兴趣的UDF
CREATE FUNCTION [dbo].[svf-Str-Tokenize](@XML xml,@Template varchar(max))
Returns varchar(max)
Begin
Select @Template = Replace(@Template,Item,Value)
From (
Select Item = '[['+attr.value('local-name(.)','varchar(100)')+']]'
,Value = attr.value('.','varchar(max)')
From @XML.nodes('/row') as xn(n)
Cross Apply xn.n.nodes('./@*') AS xa(attr)
Union All
Select Item = left(Item,charindex(']]',Item)+1)
,Value = ' '
From (
Select Item = ltrim(rtrim(B.i.value('(./text())[1]', 'varchar(max)')))
From (Select x = Cast('<x>' + replace((Select replace(replace(@Template,'[[','||[['),'||','§§Split§§') as [*] For XML Path('')),'§§Split§§','</x><x>')+'</x>' as xml).query('.')) as A
Cross Apply x.nodes('x') AS B(i)
) P
Where charindex('[[',Item)>0 and charindex(']]',Item)>0
) A
Return ltrim(rtrim(replace(replace(replace(@Template,' ','><'),'<>',''),'><',' ')))
End