Error when inserting data in non-unique index - sql-server

I have a batch job that synchronizes data between two identical databases using the MERGE statement. Sometimes, I get the following error: cannot insert duplicate key row in object 'dbo.MatchPlayerStatistics' with unique index 'IX_MatchPlayerStatistics_Player'. That does not make sense because IX_MatchPlayerStatistics_Player is not a unique index, and I am able to insert the exact same data manually. If I drop the index, insert the data, then recreate the index, it works fine.
Why does this error occur and how can I prevent it?
More information
The creation script for the table is the following:
CREATE TABLE [dbo].[MatchPlayerStatistics](
[ExternalID] [nvarchar](50) NULL,
[ProviderID] [int] NOT NULL,
[MatchID] [int] NOT NULL,
[PlayerPersonID] [int] NOT NULL,
[TeamID] [int] NOT NULL,
[YellowCards] [smallint] NULL,
[DoubleYellowCards] [smallint] NULL,
[RedCards] [smallint] NULL,
[Fouls] [smallint] NULL,
[Goals] [smallint] NULL,
[PenaltyGoals] [smallint] NULL,
[PenaltiesMissed] [smallint] NULL,
[PenaltiesSaved] [smallint] NULL,
[Shots] [smallint] NULL,
[Attacks] [smallint] NULL,
[Corners] [smallint] NULL,
[Offsides] [smallint] NULL,
[Assists] [smallint] NULL,
[OwnGoals] [smallint] NULL,
[GoalsConcedeed] [smallint] NULL,
[CreatedBy] [int] NOT NULL,
[CreatedOn] [datetime] NOT NULL,
[ModifiedBy] [int] NOT NULL,
[ModifiedOn] [datetime] NOT NULL,
CONSTRAINT [PK_MatchPlayerStatistics] PRIMARY KEY CLUSTERED
(
[ProviderID] ASC,
[MatchID] ASC,
[PlayerPersonID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
CREATE NONCLUSTERED INDEX [IX_MatchPlayerStatistics_Player] ON [dbo].[MatchPlayerStatistics]
(
[ProviderID] ASC,
[PlayerPersonID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
The MERGE statement is the following:
MERGE MatchPlayerStatistics AS M
USING (
SELECT [ExternalID]
,[ProviderID]
,[MatchID]
,[PlayerPersonID]
,[TeamID]
,[YellowCards]
,[DoubleYellowCards]
,[RedCards]
,[Fouls]
,[Goals]
,[PenaltyGoals]
,[PenaltiesMissed]
,[PenaltiesSaved]
,[Shots]
,[Attacks]
,[Corners]
,[Offsides]
,[Assists]
,[OwnGoals]
,[GoalsConcedeed]
,[CreatedBy]
,[CreatedOn]
,[ModifiedBy]
,[ModifiedOn]
FROM [Replication].MatchPlayerStatistics
WHERE ProviderID = 1
) AS R
ON (M.MatchID = R.MatchID AND M.PlayerPersonID = R.PlayerPersonID AND M.ProviderID = R.ProviderID )
WHEN NOT MATCHED
THEN
INSERT ([ExternalID]
,[ProviderID]
,[MatchID]
,[PlayerPersonID]
,[TeamID]
,[YellowCards]
,[DoubleYellowCards]
,[RedCards]
,[Fouls]
,[Goals]
,[PenaltyGoals]
,[PenaltiesMissed]
,[PenaltiesSaved]
,[Shots]
,[Attacks]
,[Corners]
,[Offsides]
,[Assists]
,[OwnGoals]
,[GoalsConcedeed]
,[CreatedBy]
,[CreatedOn]
,[ModifiedBy]
,[ModifiedOn])
VALUES
( R.[ExternalID]
,R.[ProviderID]
,R.[MatchID]
,R.[PlayerPersonID]
,R.[TeamID]
,R.[YellowCards]
,R.[DoubleYellowCards]
,R.[RedCards]
,R.[Fouls]
,R.[Goals]
,R.[PenaltyGoals]
,R.[PenaltiesMissed]
,R.[PenaltiesSaved]
,R.[Shots]
,R.[Attacks]
,R.[Corners]
,R.[Offsides]
,R.[Assists]
,R.[OwnGoals]
,R.[GoalsConcedeed]
,R.[CreatedBy]
,R.[CreatedOn]
,R.[ModifiedBy]
,R.[ModifiedOn])
WHEN MATCHED
THEN
UPDATE
SET [ExternalID] = R.[ExternalID]
,[ProviderID] = R.[ProviderID]
,[MatchID] = R.[MatchID]
,[PlayerPersonID] = R.[PlayerPersonID]
,[TeamID] = R.[TeamID]
,[YellowCards] = R.[YellowCards]
,[DoubleYellowCards] = R.[DoubleYellowCards]
,[RedCards] = R.[RedCards]
,[Fouls] = R.[Fouls]
,[Goals] = R.[Goals]
,[PenaltyGoals] = R.[PenaltyGoals]
,[PenaltiesMissed] = R.[PenaltiesMissed]
,[PenaltiesSaved] = R.[PenaltiesSaved]
,[Shots] = R.[Shots]
,[Attacks] = R.[Attacks]
,[Corners] = R.[Corners]
,[Offsides] = R.[Offsides]
,[Assists] = R.[Assists]
,[OwnGoals] = R.[OwnGoals]
,[GoalsConcedeed] = R.[GoalsConcedeed]
,[CreatedBy] = R.[CreatedBy]
,[CreatedOn] = R.[CreatedOn]
,[ModifiedBy] = R.[ModifiedBy]
,[ModifiedOn] = R.[ModifiedOn]
WHEN NOT MATCHED BY SOURCE AND M.ProviderID = 1
THEN DELETE;
The [Replication].MatchPlayerStatistics table is an intermediate table that is filled with data from the [dbo].MatchPlayerStatistics table on another copy of the database. The schema for all these tables is the same.

One idea I have is to check and see if there are triggers on the table and if one of them is inserting to another table that has a unique index.
Looking at your code, here is a completely wild guess. You are using IGNORE_DUP_KEY = OFF which is normally only used for unique constraints, so I wonder if it is considering it a unique constraint even without the unique keyword. Try creating the index without that phrase and see what happens.

Related

FREETEXT search on nvarchar column

My table is as follows:
CREATE TABLE [dbo].[Hers] (
[Material] [int] NOT NULL,
[Material_Description] [nvarchar](255) NULL,
[Material_Type] [nvarchar](255) NULL,
[Manufacturer] [nvarchar](255) NULL,
[MPN] [nvarchar](max) NULL,
[X_plant_matl_status] [nvarchar](255) NULL,
[Old_material_number] [nvarchar](255) NULL,
[Int_material_number] [int] NULL,
CONSTRAINT [PK_Hers] PRIMARY KEY CLUSTERED
(
[Material] ASC
) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
I need to use this kind of select:
SELECT *
FROM [dbo].[Hers]
WHERE FREETEXT(MPN, 'dx64')
but I have tried to create a FULLTEXT INDEX on the MPN column as follows:
CREATE FULLTEXT INDEX ON [dbo].[Hers](MPN) KEY INDEX PK_Hers WITH STOPLIST = SYSTEM;
But I am getting an error:
TYPE COLUMN option is not allowed for column types other than image or varbinary(max).
How can I create a FULLTEXT index on the MPN column?

General Trigger that updates a Master/Detail table

I've been tasked with creating a generic Trigger(one that will work on all tabled in my database) that will will fire on Insert, Delete, and Update to capture changes done on a table.
I have 2 new tables a Master Table...
CREATE TABLE [dbo].[DATA_HIL_Master](
[MasterId] [int] IDENTITY(1,1) NOT NULL,
[ReferenceTable] [nvarchar](100) NULL,
[ReferenceId] [int] NULL,
[OperationType] [smallint] NULL,
[Last_UserId_Log] [int] NULL,
[Last_WorkstationId_Log] [int] NULL,
[Last_DateTime_Log] [datetime] NULL, PRIMARY KEY CLUSTERED (
[MasterId] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS
= ON) ON [PRIMARY]
) ON [PRIMARY] GO
And then a Detail table...
CREATE TABLE [dbo].[DATA_HIL_Detail](
[DetailId] [int] IDENTITY(1,1) NOT NULL,
[MasterId] [int] NOT NULL,
[ColumnName] [nvarchar](100) NULL,
[OriginalValue] [nvarchar](max) NULL,
[ModifiedValue] [nvarchar](max) NULL,
PRIMARY KEY CLUSTERED (
[DetailId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY] GO
My trigger needs to be able to update these tables with the correct information for that update and than table. For Instance I have another table..
CREATE TABLE [dbo].[CNF_Tax2Package](
[Tax2PackageId] [int] IDENTITY(1,1) NOT NULL,
[TaxPackageId] [int] NOT NULL,
[TaxId] [int] NOT NULL,
[Last_UserId_Log] [int] NULL,
[Last_WorkstationId_Log] [int] NULL,
[Last_DateTime_Log] [datetime] NULL,
PRIMARY KEY CLUSTERED
(
[Tax2PackageId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY =
OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY],
UNIQUE NONCLUSTERED
(
[Tax2PackageId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY =
OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
EveryTime a record is change in this CNF_Tax2Package table I need to up the History tables with information
I do the following UPdate statement
Update CNF_Tax2Package
set TaxPackageid = 1,
Last_UserID_Log = 1098,
Last_WorkstationID_Log = 77,
Last_DateTime_Log = Getdate()
where Tax2PackageID = 2]
I would insert into the DATA_HIL_Master a row with the following information
[MasterId] = (NEWMasterID) [ReferenceTable] = 'CNF_Tax2Package' [ReferenceId] = 2 ---This is the primary Key of the
---table updated. [OperationType] = 'Update' [Last_UserId_Log] = 1098 [Last_WorkstationId_Log] = 77 [Last_DateTime_Log] getdate()
I would then insert into the DATA_HIL_Detail the following rows.
[DetailId] = (NEWID) [MasterId] = (NEWMasterID) (From above) [ColumnName] = 'TaxPackageid' [OriginalValue] = '19' [ModifiedValue] = '1'
[DetailId] = (NEWID) [MasterId] = (NEWMasterID) (From above) [ColumnName] = 'Last_UserID_Log' [OriginalValue] = '1954' [ModifiedValue] = '1098'
[DetailId] = (NEWID) [MasterId] = (NEWMasterID) (From above) [ColumnName] = 'Last_WorkstationId_Log' [OriginalValue] = '55' [ModifiedValue] = '77'
[DetailId] = (NEWID) [MasterId] = (NEWMasterID) (From above) [ColumnName] = 'Last_DateTime_Log' [OriginalValue] = '2018-08-18 [ModifiedValue] = getdate()
Understanding that the trigger must be generic enough to handle all tables in my database with different columns, different primary Keys

Query optimisation in SQL Server

The following is taking a long time to get executed. Considering each table has close to 50 million to 100 million rows, is there anything that I can do from the query side to get it optimized.It is a source table and involves huge data movements (insertion ranging in millions) every hour and is better off without indexes.I don't have the required access to get an execution plan from this server.
DECLARE #var INT
SELECT TOP 1 #var = s_type
FROM s_shot
WHERE s_type < 10000
ORDER BY s_type DESC;
WITH cte AS
(
SELECT
sps_id,
SUM(xin) xin,
SUM(xout) xout
FROM
s_lock
GROUP BY
sps_id
)
SELECT
A.[s_id], a.acc_id,
B.[o_type],
B.[o_id], B.[sec_id], B.[c_id],
B.[style_type_id], [s_type],
A.[end_date],
B.[mv],
b.xin + ISNULL(c.xin, 0) [xin],
b.xout + ISNULL(c.[xout], 0) xout,
b.accr_in + b.accr_inter [acc],
b.accr_in, b.accr_inter,
b.units
FROM
s_shot a WITH (NOLOCK)
JOIN
s_pos3 b WITH (NOLOCK) ON a.s_id = b.s_id
JOIN
cte c ON b.sps_id = c.sps_id
WHERE
b.is_sl = 1
AND a.end_date > DATEADD(mm, -24, GETDATE()) -- 24 months
As you can see, I want to fetch the data of last 24 months. Is there any optimization that is possible in this query so as to bring down its execution time to manageable levels.
The create table scripts are provided below.
CREATE TABLE [dbo].[s_shot]
(
[s_id] [int] IDENTITY(1,1) NOT NULL,
[acc_id] [int] NULL,
[s_type] [int] NULL,
[end_date] [datetime] NULL,
[recon] [tinyint] NULL,
[is_pers] [tinyint] NOT NULL,
CONSTRAINT [PK_s_shot_1] PRIMARY KEY NONCLUSTERED
(
[s_id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF,
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
CREATE TABLE [dbo].[s_lock]
(
[sps_id] [int] NOT NULL,
[units] [decimal](18, 5) NULL,
[accr_in] [decimal](18, 2) NULL,
[xin] [decimal](18, 2) NULL,
[xout] [decimal](18, 2) NULL,
[lock_date] [date] NOT NULL,
[accr_inter] [decimal](18, 2) NULL,
[mv] [decimal](18, 2) NULL,
CONSTRAINT [PK_s_lock] PRIMARY KEY CLUSTERED
(
[sps_id] ASC,
[lock_date] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF,
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 90) ON [PRIMARY]
) ON [PRIMARY]
CREATE TABLE [dbo].[s_pos3]
(
[sps_id] [int] IDENTITY(1,1) NOT NULL,
[s_id] [int] NOT NULL,
[o_type] [tinyint] NOT NULL,
[o_id] [int] NOT NULL,
[s_id] [int] NOT NULL,
[c_id] [int] NOT NULL,
[s_type_id] [int] NOT NULL,
[units] [decimal](18, 5) NULL,
[accr_income] [decimal](18, 2) NULL,
[distr] [decimal](18, 2) NULL,
[mv] [decimal](18, 2) NULL,
[perf_stat] [smallint] NULL,
[is_slv] [bit] NULL,
[accr_inter] [decimal](18, 2) NULL,
[perf_mtd] [decimal](18, 10) NULL,
[xin] [decimal](18, 2) NULL,
[xout] [decimal](18, 2) NULL,
[a_s_type_id] [int] NULL,
CONSTRAINT [PK_s_pos3] PRIMARY KEY NONCLUSTERED
(
[sps_id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF,
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 90) ON [PRIMARY]
) ON [PRIMARY]
Any help is appreciated.
Edit: Updated indexing details

SQL Select with Join Bringing Odd Result

I know this kind of problem can happen but I have no idea on figuring it out (also, it is in Portuguese, so I will try my best to illustrate my question in English, translating the database structure, fields, etc).
These are the 4 tables that I need for this query:
- Agenda_Cliente (this is the Client table);
- Agenda_Imposto (this is the Taxes table - description for each tax ID);
- Agenda_ClienteImposto (NxN table - relates each Client to the taxes he or she pays);
- Agenda_LogAgenda (that's the core of the query: it contains which tax (by ID: CodigoImposto) was sent to a specific client (by ID as well: CodigoCliente), when the tax was sent (DataHoraEnvio) and when it was accessed (DataHoraAcesso).
The strctures are the following:
CREATE TABLE [dbo].[Agenda_Cliente](
[CodigoCliente] [bigint] IDENTITY(1,1) NOT NULL,
[CodigoEscritorio] [int] NOT NULL,
[RazaoSocial] [varchar](60) NOT NULL,
[NomeFantasia] [varchar](60) NOT NULL,
[Email] [varchar](60) NOT NULL,
[TelefoneComercial] [bigint] NOT NULL,
[TelefoneCelular1] [bigint] NOT NULL,
[TelefoneCelular2] [bigint] NOT NULL,
[CnpjCpf] [bigint] NOT NULL,
[Cep] [int] NOT NULL,
[Endereco] [varchar](80) NOT NULL,
[Bairro] [varchar](60) NOT NULL,
[Municipio] [varchar](60) NOT NULL,
[Estado] [char](2) NOT NULL,
[RegimeTributacao] [int] NOT NULL,
[FlagAtivo] [bit] NOT NULL,
PRIMARY KEY CLUSTERED
(
[CodigoCliente] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
CREATE TABLE [dbo].[Agenda_Imposto](
[CodigoImposto] [int] IDENTITY(1,1) NOT NULL,
[DescricaoImposto] [varchar](30) NOT NULL,
[TipoImposto] [int] NOT NULL,
[DeptoResponsavel] [int] NOT NULL,
PRIMARY KEY CLUSTERED
(
[CodigoImposto] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
CREATE TABLE [dbo].[Agenda_ClienteImposto](
[CodigoClienteImposto] [bigint] IDENTITY(1,1) NOT NULL,
[CodigoCliente] [bigint] NOT NULL,
[CodigoImposto] [int] NOT NULL,
[DataLimite] [int] NOT NULL,
PRIMARY KEY CLUSTERED
(
[CodigoClienteImposto] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
Also, the FOREIGN KEYS are all OK and working.
So, the problem is: I have the following SQL SELECT query:
SELECT c.CnpjCpf, c.NomeFantasia, i.DescricaoImposto, ci.DataLimite, la.DataHoraEnvio, la.DataHoraAcesso
FROM Agenda_Cliente c
JOIN Agenda_ClienteImposto ci ON ci.CodigoCliente = c.CodigoCliente
JOIN Agenda_Imposto i ON i.CodigoImposto = ci.CodigoImposto
LEFT JOIN Agenda_LogAgenda la ON la.CodigoImposto = i.CodigoImposto
WHERE c.CodigoEscritorio = 1
ORDER BY c.NomeFantasia ASC, ci.DataLimite ASC
It's bringing me this:
But I need it to bring me this:
And if I SELECT * at the Calendar log (Agenda_LogAgenda), there's only one record.
It seems to me that it's something to do with Agenda_ClienteImposto, as far as I tried here, but it may be something about the JOIN clause that I'm not getting, because it's applying the result for "Empresa 1" in "Empresa 3", but "Empresa 3" does not exist in Agenda_LogAgenda.
Any help is appreciated.
Thanks!
The left join to Agenda_LogAgenda is only on CodingoImposto. From the values in the query, 'CRF' probably does exist. Add NomFantasia to the ON clause of the left join.

Querying 3 tables where I'm looking for non-matches

I have three tables: LitHold, LitHoldDetails and EmailTemplate. The definitions are as follows.
CREATE TABLE [dbo].[LitHold](
[LitholdID] [int] IDENTITY(1,1) NOT NULL,
[LitHoldStatusID] [tinyint] NOT NULL,
[EmailReminderID] [tinyint] NULL,
[ApprovedDate] [datetime] NULL,
[TerminatedDate] [datetime] NULL,
CONSTRAINT [PK_Lithold] PRIMARY KEY CLUSTERED
(
[LitholdID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
CREATE TABLE [dbo].[LitHoldDetails](
[LitHoldDetailsID] [int] IDENTITY(1,1) NOT NULL,
[LitholdID] [int] NOT NULL,
[VersionID] [int] NOT NULL,
[Description] [varchar](300) NULL,
[ResAttorneyID] [varchar](10) NOT NULL,
[Comments] [varchar](1000) NULL,
[HoldStartDate] [datetime] NULL,
[HoldEndDate] [datetime] NULL,
[CreatedDate] [datetime] NOT NULL,
[CreatedByLogin] [varchar](10) NULL,
CONSTRAINT [PK_LitholdDetails] PRIMARY KEY CLUSTERED
(
[LitHoldDetailsID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
CREATE TABLE [dbo].[EmailTemplate](
[TemplateID] [int] IDENTITY(1,1) NOT NULL,
[LitHoldDetailsID] [int] NOT NULL,
[From] [varchar](50) NULL,
[To] [varchar](2000) NULL,
[CC] [varchar](500) NULL,
[BCC] [varchar](500) NULL,
[Subject] [nvarchar](200) NULL,
[MessageBody] [nvarchar](max) NULL,
[SendDate] [datetime] NULL,
[IsDefault] [bit] NOT NULL,
CONSTRAINT [PK_EmailTemplate] PRIMARY KEY CLUSTERED
(
[TemplateID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
For each LitHold, there can be multiple LitHoldDetails. For each LitHoldDetail, there should be one EmailTemplate. I recently found that some LitHoldDetails do NOT have EmailTemplates. We're still working in development on this project, so this isn't a big deal. However, we want to get the EmailTemplate data into the database. The situation is that for each LitHold, there is at least one LitHoldDetail that has an EmailTemplate. I would like to duplicate this EmailTemplate data for all the LitHoldDetails that a) have the same LitHoldID and b) do not have an EmailTemplate. One of the approaches I've tried is:
insert into EmailTemplate
(LitHoldDetailsID, [From], [To], CC, BCC, Subject, MessageBody, SendDate, IsDefault)
(select (select top 1 LitHoldDetailsID from LitHoldDetails where LitholdID = d.LitholdID and LitHoldDetailsID <> e.LitHoldDetailsID), [To], CC, BCC, Subject, MessageBody, SendDate, IsDefault from
EmailTemplate e inner join LitHoldDetails d on e.LitHoldDetailsID = d.LitHoldDetailsID)
but this gets me multiple rows for some LitHoldDetails, with different EmailTemplate data, and some rows where LitHoldDetails is NULL. How can I accomplish this? I'm using SQL Server 2008.
Try inserting this:
SELECT lhd.LitHoldDetailsID, CloneEmailTemplate.[From], ...
FROM LitHoldDetails lhd
CROSS APPLY (SELECT TOP 1 et.*
FROM EmailTemplate et
JOIN LitHoldDetails lhd2 ON lhd2.LitHoldDetailsID = et.LitHoldDetailsID
WHERE lhd2.LitHoldID = lhd.LitHoldID
) AS CloneEmailTemplate
WHERE NOT EXISTS (SELECT 1
FROM EmailTemplate et2
WHERE et2.LitHoldDetailsID = lhd.LitHoldDetailsID
)

Resources