Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit d76ee0a

Browse files
Added try/catch.
1 parent ac106e7 commit d76ee0a

File tree

1 file changed

+131
-85
lines changed

1 file changed

+131
-85
lines changed

‎docs/findings/SQLCodeDevelopment.md

Lines changed: 131 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -150,50 +150,71 @@ Consider using [sp_CRUDGen](https://github.com/kevinmartintech/sp_CRUDGen) to ge
150150
```sql
151151
SET NOCOUNT, XACT_ABORT ON;
152152

153-
BEGIN TRANSACTION;
153+
BEGIN TRY
154+
BEGIN TRANSACTION;
154155

155-
UPDATE
156-
dbo.Person WITH (UPDLOCK, SERIALIZABLE)
157-
SET
158-
FirstName = 'Kevin'
159-
WHERE
160-
LastName = 'Martin';
156+
UPDATE
157+
dbo.Person WITH (UPDLOCK, SERIALIZABLE)
158+
SET
159+
FirstName = 'Kevin'
160+
WHERE LastName = 'Martin';
161161

162-
IF @@ROWCOUNT = 0
162+
IF @@ROWCOUNT = 0
163163
BEGIN
164164
INSERT dbo.Person (FirstName, LastName) VALUES ('Kevin', 'Martin');
165165
END;
166166

167-
COMMIT TRANSACTION;
167+
COMMIT TRANSACTION;
168+
END TRY
169+
BEGIN CATCH
170+
IF @@TRANCOUNT > 0
171+
BEGIN
172+
ROLLBACK TRANSACTION;
173+
END;
174+
175+
THROW;
176+
END CATCH;
168177
```
169178

170179
**Use this UPSERT pattern when a record insert is more likely:** Don't worry about checking for a records existence just perform the insert.
171180

172181
```sql
173182
SET NOCOUNT, XACT_ABORT ON;
174183

175-
BEGIN TRANSACTION;
184+
BEGIN TRY
185+
BEGIN TRANSACTION;
176186

177-
INSERT dbo.Person (FirstName, LastName)
178-
SELECT
179-
'Kevin'
180-
,'Martin'
181-
WHERE
182-
NOT EXISTS (
187+
INSERT dbo.Person
188+
(
189+
FirstName,
190+
LastName
191+
)
183192
SELECT
184-
1
185-
FROM
186-
dbo.Person WITH (UPDLOCK, SERIALIZABLE)
187-
WHERE
188-
LastName = 'Martin'
189-
);
193+
'Kevin',
194+
'Martin'
195+
WHERE NOT EXISTS
196+
(
197+
SELECT
198+
1
199+
FROM dbo.Person WITH (UPDLOCK, SERIALIZABLE)
200+
WHERE LastName = 'Martin'
201+
);
190202

191-
IF @@ROWCOUNT = 0
203+
IF @@ROWCOUNT = 0
192204
BEGIN
193205
UPDATE dbo.Person SET FirstName = 'Kevin' WHERE LastName = 'Martin';
194206
END;
195207

196-
COMMIT TRANSACTION;
208+
COMMIT TRANSACTION;
209+
END TRY
210+
BEGIN CATCH
211+
IF @@TRANCOUNT > 0
212+
BEGIN
213+
ROLLBACK TRANSACTION;
214+
END;
215+
216+
THROW;
217+
END CATCH;
197218
```
198219

199220
**Use this UPSERT pattern to allow the client application to handle the exception:** Ensure you handle the exception in your code.
@@ -220,61 +241,77 @@ For JSON, XML or comma-separated list ensure you insert the records into a tempo
220241
```sql
221242
SET NOCOUNT, XACT_ABORT ON;
222243

223-
BEGIN TRANSACTION;
224-
225-
/***************************************************************
226-
** Create temp table to store the updates
227-
****************************************************************/
228-
CREATE TABLE #Update (
229-
FirstName varchar(50) NOT NULL
230-
,LastName varchar(50) NOT NULL
231-
);
232-
233-
INSERT INTO #Update (FirstName, LastName)
234-
VALUES ('Kevin', 'Martin')
235-
,('Jean-Luc', 'Picard');
236-
237-
238-
/***************************************************************
239-
** Perform Updates (WHEN MATCHED)
240-
****************************************************************/
241-
UPDATE
242-
P WITH (UPDLOCK, SERIALIZABLE)
243-
SET
244-
P.FirstName = U.FirstName
245-
FROM
246-
dbo.Person AS P
247-
INNER JOIN #Update AS U ON P.LastName = U.LastName;
248-
249-
250-
/***************************************************************
251-
** Perform Inserts (WHEN NOT MATCHED [BY TARGET])
252-
****************************************************************/
253-
INSERT dbo.Person (FirstName, LastName)
254-
SELECT
255-
U.FirstName
256-
,U.LastName
257-
FROM
258-
#Update AS U
259-
WHERE
260-
NOT EXISTS (
261-
SELECT * FROM dbo.Person AS P WHERE P.LastName = U.LastName
262-
);
263-
244+
BEGIN TRY
245+
BEGIN TRANSACTION;
264246

265-
/***************************************************************
266-
** Perform Deletes (WHEN NOT MATCHED BY SOURCE)
267-
****************************************************************/
268-
DELETE
269-
P
270-
FROM
271-
dbo.Person AS P
272-
LEFT OUTER JOIN #Update AS U ON P.LastName = U.LastName
273-
WHERE
274-
U.LastName IS NULL;
247+
/***************************************************************
248+
** Create temp table to store the updates
249+
****************************************************************/
250+
CREATE TABLE #Update
251+
(
252+
FirstName varchar(50) NOT NULL,
253+
LastName varchar(50) NOT NULL
254+
);
255+
256+
INSERT INTO #Update
257+
(
258+
FirstName,
259+
LastName
260+
)
261+
VALUES
262+
('Kevin', 'Martin'),
263+
('Jean-Luc', 'Picard');
264+
265+
266+
/***************************************************************
267+
** Perform Updates (WHEN MATCHED)
268+
****************************************************************/
269+
UPDATE
270+
P WITH (UPDLOCK, SERIALIZABLE)
271+
SET
272+
P.FirstName = U.FirstName
273+
FROM dbo.Person AS P
274+
INNER JOIN #Update AS U
275+
ON P.LastName = U.LastName;
276+
277+
278+
/***************************************************************
279+
** Perform Inserts (WHEN NOT MATCHED [BY TARGET])
280+
****************************************************************/
281+
INSERT dbo.Person
282+
(
283+
FirstName,
284+
LastName
285+
)
286+
SELECT
287+
U.FirstName,
288+
U.LastName
289+
FROM #Update AS U
290+
WHERE NOT EXISTS
291+
(
292+
SELECT * FROM dbo.Person AS P WHERE P.LastName = U.LastName
293+
);
294+
295+
296+
/***************************************************************
297+
** Perform Deletes (WHEN NOT MATCHED BY SOURCE)
298+
****************************************************************/
299+
DELETE P
300+
FROM dbo.Person AS P
301+
LEFT OUTER JOIN #Update AS U
302+
ON P.LastName = U.LastName
303+
WHERE U.LastName IS NULL;
275304

305+
COMMIT TRANSACTION;
306+
END TRY
307+
BEGIN CATCH
308+
IF @@TRANCOUNT > 0
309+
BEGIN
310+
ROLLBACK TRANSACTION;
311+
END;
276312

277-
COMMIT TRANSACTION;
313+
THROW;
314+
END CATCH;
278315
```
279316

280317
**Do not use this UPSERT pattern:** It will produce primary key violations when run concurrently.
@@ -331,19 +368,28 @@ WHEN NOT MATCHED BY SOURCE THEN
331368
This method will not prevent a race condition and the last update will win.
332369

333370
```sql
334-
SET NOCOUNT, XACT_ABORT ON;
335-
BEGIN TRANSACTION;
371+
BEGIN TRY
372+
BEGIN TRANSACTION;
336373

337-
IF EXISTS (SELECT * FROM dbo.Person WITH (UPDLOCK, SERIALIZABLE) WHERE PersonId = @PersonId)
338-
BEGIN
339-
UPDATE dbo.Person SET FirstName = @FirstName WHERE PersonId = @PersonId;
340-
END;
341-
ELSE
374+
IF EXISTS (SELECT * FROM dbo.Person WITH (UPDLOCK, SERIALIZABLE) WHERE PersonId = @PersonId)
375+
BEGIN
376+
UPDATE dbo.Person SET FirstName = @FirstName WHERE PersonId = @PersonId;
377+
END;
378+
ELSE
379+
BEGIN
380+
INSERT dbo.Person (PersonId, FirstName) VALUES (@PersonId, @FirstName);
381+
END;
382+
383+
COMMIT TRANSACTION;
384+
END TRY
385+
BEGIN CATCH
386+
IF @@TRANCOUNT > 0
342387
BEGIN
343-
INSERT dbo.Person (PersonId, FirstName) VALUES (@PersonId, @FirstName);
388+
ROLLBACK TRANSACTION;
344389
END;
345390

346-
COMMIT TRANSACTION;
391+
THROW;
392+
END CATCH;
347393
```
348394

349395
[Back to top](#top)

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /