SQL Stored Proceedures

Let AI do it

Stop Skipping the Stored Procedure

The issue is not that stored procedures are slow. The issue is the queue in front of them.

A developer on the project needs a write. The person who owns stored procedures is on something else. The ticket sits. The release does not. So the developer puts the SQL in the application, or asks for a login that can write tables directly, and ships. Upper management hears "SQL write" and treats it as the same thing as permission to use a stored procedure. Both moves are wrong. They feel like speed. They are a permission change dressed up as a shortcut.

The fix is not to wait longer, and it is not to hand the application a pen for the tables. The fix is a writer that has no other job. An AI that only writes stored procedures is almost never behind, and on a narrow task like this it rarely misses. The procedure still exists. The wait does not.



What people skip, and why

The pattern is ordinary. The screen is done. The API is done. The missing piece is one insert, one update, one lookup that has to be right. That piece is supposed to be a procedure: named, parameterized, granted, reviewed. The person who writes those is good, and also busy. They have a queue. The application developer does not want to wait in it. They are not wrong about the wait. They are wrong about the workaround.

So the SQL lands in a repository. A string in a service. A script someone runs by hand "just for this release." Sometimes it is parameterized. Often it is assembled. It works on the developer's database. It gets promoted because the feature cannot slip. Six months later nobody can say, from the server, what the application is allowed to do. They can only say the login can write.

That is the failure. Not the impatience. The decision to delete the boundary because the boundary had a human in front of it.



SQL write is not execute

Management collapses two grants into one sentence. "They need to write to SQL." That can mean two completely different things.

Permission to execute a stored procedure means the application may call one named operation. CreateInvoice. AssignTech. CloseTicket. The procedure decides which tables move, in what order, inside a transaction, with the checks the business actually cares about. The login does not need to see the tables. It needs to be allowed to run that one verb.

Permission to write SQL against the tables means the application may insert, update, and delete whatever those tables will accept, from whatever code is deployed this week. The database is no longer the contract. The application is, and the application is a pile of copies. Every service, every script, every hurried hotfix is a second writer with no shared name.

Those are not styles. They are different security models.

A procedure is a door with a label. Table write is the keys to the building. If the application login can update the payments table, it can update any row it can name, including ones this screen was never supposed to touch. If it can only execute CloseTicket, the worst bug is a bad call to CloseTicket. You can revoke one procedure without turning off the product. You cannot half-revoke "this login may write."

Ownership matters the same way. The procedure can be owned by a schema the application cannot alter. The application calls it. A DBA, or the procedure writer, changes the body when the rule changes. Callers keep the same name. If the SQL lives in ten services, a rule change is a scavenger hunt and a coordinated deploy. People skip that hunt. The rule drifts. Then someone says the database is "hard to change," when what is hard is finding every place a developer got tired of waiting.



What the procedure is for

A stored procedure is not a religious artifact. It is the API of the database.

It takes parameters, not concatenated text. That alone removes a class of injection that shows up the moment someone builds a WHERE clause out of a query string because "it was only an internal tool."

It is one place for the transaction. The debit and the credit, the status change and the audit row, happen together or not at all. An application that writes three statements from a web request has three chances to die in the middle, and a user who refreshes.

It is one place for the plan. SQL Server can cache and reuse a parameterized procedure. Ad hoc SQL that changes shape — an extra AND this week, a different column list the next — gets a new plan every time, or a bad one, and you will not notice until the report that used to take a second takes a minute.

It is one place to review. A human, or a test, can read CreateInvoice and say what it is allowed to do. Nobody can review "whatever the C# repository felt like emitting" without reading every caller.

It is the thing you grant. Grant execute on the procedure to the application role. Do not grant insert, update, or delete on the tables to that role. If a developer "needs SQL write" to finish a ticket, the ticket is not finished. The procedure is missing.

The bottleneck was the person, not the pattern

The stored-procedure specialist is often right, and still the reason the pattern dies. They are one queue. They context-switch. They go to the meeting. They are careful, which is why you wanted them, and careful has a wait. Application developers are measured on the screen shipping. They will route around a wait. Every time. Blaming them for that is how you get speeches. The system already told them the procedure is optional.



Upper management makes it worse when they treat "access to SQL" as a favor. A write grant feels like unblocking. It is a policy change. The person who approved it usually cannot see the difference between "call this procedure" and "this login may change these rows." They should not have to become a DBA to approve a feature. They do need a rule they can say out loud: the application does not write tables. It calls procedures. If the procedure is not ready, the feature is not ready. Then you remove the wait, instead of removing the rule.



Give that job to something that has no other job

This is a good job for an AI, and a bad job for a shared human queue.

The input is small and checkable. Here is the table. Here is the rule. Here are the parameters. Here is what must be true before the write, and what the caller gets back. Write the procedure. Name it. Parameterize it. Put the grant in the same script, execute only, no table rights for the application role.

That is a narrow task. Narrow tasks are where a model rarely errors, because the spec does not depend on taste. It depends on the schema in front of it and the contract you wrote down. It does not get pulled into a production incident halfway through the create statement. It does not have three other procedures "almost done." If writing procedures is all it has to do, it is not behind. The developer asks. The procedure comes back in the same sitting. The reason to skip it disappears.

This only works if you keep the job narrow.

The AI writes procedures. It does not get sysadmin. It does not redesign the database because a column name annoyed it. It does not run the script on production because the chat felt confident. A person, or a pipeline, applies the script to a database that is not production first. A test calls the procedure the way the application will. If the test fails, the procedure is wrong, even if the prose around it sounded finished. Rarely wrong is not never wrong. The point of the procedure is that you can see the mistake in one object before the application is allowed to call it.

Do not let the model invent the business rule. The developer still says what the operation is. The AI writes the SQL Server object that implements that operation, consistently, with the same shape every time: parameters, transaction, checks, return, grant. That consistency is the part a tired specialist drops at 4 p.m., and the part a bypassing developer never writes at all.

When the procedure needs a human, it is because the rule is unclear, not because the typing is scarce. Unclear rules should wait. That wait is real. Waiting for someone to type CREATE PROCEDURE is not.

The rule

Say it so management can repeat it.

The application role executes stored procedures. It does not get SQL write on the tables. Those are different permissions. Approving one is not approving the other.

If a feature needs a write, it needs a procedure. The procedure is the feature's database API. Shipping the screen without it is shipping an open login.

The procedure writer is no longer a person you wait on. It is a worker whose only queue is procedures. Developers stop routing around it because there is nothing to route around. The specialist, if you still have one, reviews the odd procedure that changes money or identity. They stop being the reason the rest of the system writes SQL from the application.

That is the whole correction. Do not pass on the procedure because the person is busy. Do not treat a write grant as a substitute. Keep an AI on that one job, with no right to the tables beyond the scripts you choose to apply. The procedure shows up. The login stays small. The shortcut stops looking like speed.