Use when writing or reviewing MSSQL/T-SQL, creating stored procedures, designing table schemas, writing views, building migrations, defining custom types, or architecting a SQL Server application database. Also use when writing RAISERROR patterns, CHECK constraints with scalar functions, base/subtype table hierarchies, composite key designs, role-scoped views with row-level security, or idempotent DDL scripts. If you are touching MSSQL for an application database, use this skill. Not for PostgreSQL, MySQL, Oracle, or SQLite — patterns are SQL Server-specific.
95
94%
Does it follow best practices?
Impact
98%
1.81xAverage score across 5 eval scenarios
Passed
No known issues
{
"context": "Tests whether the agent follows the stored procedure structure instructions: the 5-block structure, correct _trx/_utx suffixes and transaction count validation, GOTO-based error handling (not TRY-CATCH), DML error checking with @@ROWCOUNT/@@ERROR captured atomically, structured RAISERROR codes, and transaction name matching procedure name.",
"type": "weighted_checklist",
"checklist": [
{
"name": "_utx suffix for payment procedure",
"description": "The payment-recording procedure name ends with _utx (indicating it is a transaction participant, not owner)",
"max_score": 8
},
{
"name": "_trx suffix for reservation procedure",
"description": "The reservation-creation procedure name ends with _trx (indicating it owns the transaction)",
"max_score": 8
},
{
"name": "_utx validates @@TRANCOUNT > 0",
"description": "The _utx procedure checks IF (@@TRANCOUNT = 0) and raises an error (exits) if not inside a transaction",
"max_score": 8
},
{
"name": "_trx validates @@TRANCOUNT = 0",
"description": "The _trx procedure checks IF (@@TRANCOUNT > 0) and raises an error (exits) if already inside a transaction",
"max_score": 8
},
{
"name": "No TRY-CATCH for DML",
"description": "Neither procedure uses TRY-CATCH blocks around INSERT, UPDATE, or DELETE operations",
"max_score": 8
},
{
"name": "GOTO exit labels present",
"description": "Both procedures use GOTO with labeled exit points (e.g., EXIT_ERROR, EXIT_TRANSACTION) rather than RETURN statements inline with error handling",
"max_score": 8
},
{
"name": "Atomic @@ROWCOUNT + @@ERROR capture",
"description": "After each DML, @@ROWCOUNT and @@ERROR are captured together in a single SELECT statement (SELECT @RowCnt = @@ROWCOUNT, @ErrNo = @@ERROR)",
"max_score": 10
},
{
"name": "Structured RAISERROR codes",
"description": "RAISERROR calls use numeric codes in the 50000+ range (e.g., 50002 for missing input, 50004 for not added, 50005 for not modified)",
"max_score": 8
},
{
"name": "Transaction name matches procedure",
"description": "The BEGIN TRANSACTION and COMMIT/ROLLBACK TRANSACTION statements in the _trx procedure use the procedure name as the transaction name",
"max_score": 8
},
{
"name": "_trx calls _utx inside transaction",
"description": "The _trx procedure calls the _utx procedure after BEGIN TRANSACTION (not before) and checks the return value of EXEC",
"max_score": 8
},
{
"name": "No SQL keyword verbs",
"description": "Procedure names do NOT use SQL keyword verbs: no Create, Update, Delete, Insert, or Select as the verb prefix",
"max_score": 8
},
{
"name": "DECLARE block present",
"description": "Both procedures declare @ErrNo and @RowCnt INT variables in a declaration block at the start",
"max_score": 10
}
]
}