{"id":105418,"date":"2025-04-16T03:29:00","date_gmt":"2025-04-16T03:29:00","guid":{"rendered":"https:\/\/www.red-gate.com\/simple-talk\/?p=105418"},"modified":"2025-02-27T15:39:24","modified_gmt":"2025-02-27T15:39:24","slug":"llm-technical-editor-test-chatgpt-with-a-very-wrong-article","status":"publish","type":"post","link":"https:\/\/www.red-gate.com\/simple-talk\/blogs\/llm-technical-editor-test-chatgpt-with-a-very-wrong-article\/","title":{"rendered":"LLM Technical Editor Test \u2013 ChatGPT with a VERY wrong article"},"content":{"rendered":"\n<p>As started in <a href=\"https:\/\/www.red-gate.com\/simple-talk\/blogs\/new-series-testing-llms-as-technical-editors\/\u2197\">part 1<\/a> of this series, I have set out to test an LLMs ability to technical edit. For my first set of tests, I am using a pair of articles I created, filled with very bad advice. The advice is the same for both articles, but what differs is the intro and the conclusion. One says the advice is good, the other said it is bad. It is all very very bad, including a really terrible <code>SELECT<\/code> statement versus loop construct that will cause an eternal loop that inserts into a temporary table.<\/p>\n\n\n\n<p>My goal is to see how much of that advice will be noted as bad, and if it says anything nice at all about the text, etc. If you want to see the entire documents, you can get them <a href=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2025\/02\/LLM_Test-articles_with_very_bad_advice.zip\">here in a zip file<\/a>, both in text and word document formats.<\/p>\n\n\n\n<p>If you are questioning this concept of using very poorly written source material, that is understandable. After I finished this article\u2019s first pass, I realized that if I was going to really do a good job testing these models, I am going to need to test with more subtle incorrectness mixed in with correct statements. However, I feel as if there is something to learn from this first experiments which are chronicled here in part 2 and will be with part 3 as well, before I change gears.<\/p>\n\n\n\n<p>Before I get started, I asked ChatGPT \u201cwhat model of ChatGPT am I using now?\u201d just to show you where it is at. The reply was:<\/p>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:60px\"><\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<p><strong>\u201cYou&#8217;re currently using ChatGPT-4 with additional features enabled, such as code execution, web browsing, and a document editor for enhanced interactivity and productivity.\u201d<\/strong><\/p>\n<\/div>\n<\/div>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p><\/p>\n\n\n\n<p>So whatever that meant on February 1, 2025, it is what it is.\u201cYou&#8217;re currently using ChatGPT-4 with additional features enabled, such as code execution, web browsing, and a document editor for enhanced interactivity and productivity.\u201d<\/p>\n<\/blockquote>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-getting-started-with-chatgpt\">Getting started with ChatGPT<\/h2>\n\n\n\n<p>Okay, I have not used ChatGPT on this document yet at all. I do not have a paid account, so I will be using the free version, with a login. I will try two tests. First, the entire documents will be reviewed and I will give the highlights. Then I will take a section and dig into whatever feedback it gives me.<\/p>\n\n\n\n<p>The phrase I have found works with Copilot quite well to get it to only give me technology issues has been: \u201cPlease review the following document in terms of technology\u201d. So I will be using this as my starting point, though I may change it up a little here and there along the way.<\/p>\n\n\n\n<p>Disclosure: as I originally typed this introduction, I had not used ChatGPT for any work with this document at all, nor had I used Copilot. I just created the documents and edited them with Grammarly.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-document-advocating-for-the-advice\">Document advocating for the advice<\/h2>\n\n\n\n<p>So here we go. I typed:<\/p>\n\n\n\n<p><em>\u201cPlease review the following document in terms of technology\u201d<\/em><\/p>\n\n\n\n<p>And then pasted the document with the header that said this was good advice. The result, was oddly polite, but correct. It starts out:<\/p>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:60px\"><\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<p><strong>\u201cThis document contains several practices and recommendations for SQL Server administrators. However, many of them reflect misconceptions, outdated practices, or outright harmful advice in the realm of modern SQL Server administration. Below is a review of each suggestion from a technical standpoint.\u201d<\/strong><\/p>\n<\/div>\n<\/div>\n\n\n\n<p>I liked that it didn\u2019t put any positive or negative in the first sentence. It just said \u201cit contains some stuff.\u201d Kind of like a person might when trying to say <strong><em>ANYTHING<\/em><\/strong> positive about an article that is such garbage.<\/p>\n\n\n\n<p>It ends with:<\/p>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:60px\"><\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<p><strong>\u201cWhile some advice here might be well-intentioned, much of it is outdated, misleading, or counterproductive in modern SQL Server environments. Following these suggestions could lead to security vulnerabilities, performance issues, and operational inefficiencies.\u201d<\/strong><\/p>\n<\/div>\n<\/div>\n\n\n\n<p>Well-intentioned. It is almost like it\u2019s trying to be too kind here. It goes on to offer to rewrite the document for me. I was not expecting this, but that will be my next thing to try. I saved the full text of the results here: <a href=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2025\/02\/LLM-Technical-Editor-Test-\u2013-ChatGPT_Results-1-Advocating.txt\">results<\/a> if you wish to review.<\/p>\n\n\n\n<p>The main thing is I am not getting any deeper information. For example, one section in my document contains the following incomprehensibly wrong content:<\/p>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:60px\"><\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<p>\u201c- SQL Server works better with LOOPING code<\/p>\n\n\n\n<p>If you want to filter from a set of data, the best way is to use a WHILE WEND construct and do the filtering ROW BY ROW. For example, say you have a table with a million rows. You can write:<\/p>\n\n\n\n<p>SELECT *<br>FROM TableName<br>WHERE Criteria = False;<\/p>\n\n\n\n<p>But it is often far faster to use a loop such as:<\/p>\n\n\n\n<p>CREATE TEMP TABLE #Results<br>WHILE (RowsStillInTable)<br>  BEGIN<br>      INSERT INTO #Results<br>      SELECT TOP 1 *<br>      FROM TableName<br>      WHERE Criteria = False;<br><br>      IF @@RowsCount = 0<br>            Break;<br>WEND;<\/p>\n\n\n\n<p>By using the TOP 1 modifier, this allows each iteration to execute much faster than the SELECT statement that needs to touch every row in the table simultaneously.\u201d<\/p>\n<\/div>\n<\/div>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:60px\"><\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<p>\u201cSQL Server Works Better with Looping Code<\/p>\n\n\n\n<p>Review: Iterative row-by-row processing (RBAR\u2014&#8221;Row By Agonizing Row&#8221;) is inefficient. Set-based operations are the foundation of SQL and are far more performant.<\/p>\n\n\n\n<p>Recommendation: Use set-based SQL queries and avoid looping constructs whenever possible.\u201d<\/p>\n<\/div>\n<\/div>\n\n\n\n<p>And the reply says:<\/p>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:60px\"><\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<p>\u201c<strong>SQL Server Works Better with Looping Code<\/strong><\/p>\n\n\n\n<p><strong>Review: Iterative row-by-row processing (RBAR\u2014&#8221;Row By Agonizing Row&#8221;) is inefficient. Set-based operations are the foundation of SQL and are far more performant.<\/strong><\/p>\n\n\n\n<p><strong>Recommendation: Use set-based SQL queries and avoid looping constructs whenever possible.\u201d<\/strong><\/p>\n<\/div>\n<\/div>\n\n\n\n<p>Reading over that advice, you should see the code itself is completely wrong. After I let it do a rewrite, I am going to ask it to tell me more about what is wrong in that section.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-let-s-see-if-it-can-rewrite-this-for-me\">Let\u2019s see if it can rewrite this for me?<\/h3>\n\n\n\n<p>Next, I say yes to letting it rewrite the article for me. You can easily tell that the output it is AI generated, if for no other reason than the overuse of bullet points. The tips come out in a very basic manner, but the tips are generally ok. The document is basically lifeless and example-less, but correct. The replacement for my terrible example code that had code:<\/p>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:60px\"><\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<p><strong>\u201c12. Avoid Row-by-Row Processing<\/strong><\/p>\n\n\n\n<p><strong>Row-by-row processing (RBAR) is inefficient. SQL Server is optimized for set-based operations. To enhance performance:<\/strong><\/p>\n\n\n<div class=\"block-core-list\">\n<ul class=\"wp-block-list\">\n<li><strong>Use set-based queries whenever possible.<\/strong><\/li>\n\n\n\n<li><strong>Rewrite RBAR logic into efficient set-based T-SQL statements.\u201d<\/strong><\/li>\n<\/ul>\n<\/div><\/div>\n<\/div>\n\n\n\n<p>RBAR? I don\u2019t love that term to start with, but it does not stand for Row-by-row processing, it stands for Row By Agonizing Row. I don\u2019t love it because sometimes you do need to loop. And it makes it sound too much like a human doing work. (Or maybe because I didn\u2019t come up with it, who knows.<\/p>\n\n\n\n<p>The biggest issue is that it didn\u2019t even try to understand my code, or anything of the sort. It simply gave a bit of advice.<\/p>\n\n\n\n<p>The complete rewrite results can be <a href=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2025\/02\/LLM-Technical-Editor-Test-\u2013-ChatGPT_Rewrite-1-Advocating.txt\">found here<\/a>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-digging-into-the-advice\">Digging into the advice<\/h3>\n\n\n\n<p>Finally, I asked it:<\/p>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:60px\"><\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:66.66%\">\n<p>\u201cGive me advice on this section alone:\u201d<\/p>\n<\/div>\n<\/div>\n\n\n\n<p>And pasted in the section 12 as it was shown earlier, with all the really terrible code. The reply:<\/p>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:60px\"><\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<p><strong>\u201cIssues with the Given Advice<\/strong><\/p>\n\n\n<div class=\"block-core-list\">\n<ul class=\"wp-block-list\">\n<li><strong>Inefficiency of Row-by-Row Processing:<\/strong><\/li>\n\n\n\n<li><strong>Using a loop to process rows one at a time introduces significant overhead.<\/strong><\/li>\n\n\n\n<li><strong>Each iteration involves separate queries, context switches, and transactions, which degrade performance.<\/strong><\/li>\n<\/ul>\n<\/div>\n\n\n<p><strong>Misconception About SELECT Efficiency:<\/strong><\/p>\n\n\n<div class=\"block-core-list\">\n<ul class=\"wp-block-list\">\n<li><strong>A SELECT query with proper indexing can filter data efficiently without requiring loops.<\/strong><\/li>\n\n\n\n<li><strong>The suggestion to use TOP 1 in a loop does not improve performance for large datasets; it just splits the work inefficiently.<\/strong><\/li>\n<\/ul>\n<\/div>\n\n\n<p><strong>Unnecessary Complexity:<\/strong><\/p>\n\n\n<div class=\"block-core-list\">\n<ul class=\"wp-block-list\">\n<li><strong>The loop adds complexity to the code and increases the likelihood of bugs.<\/strong><\/li>\n\n\n\n<li><strong>Temporary tables like #Results are not needed for filtering data in this scenario.<\/strong><\/li>\n<\/ul>\n<\/div>\n\n\n<p><strong>Correct Approach: Use Set-Based Queries<\/strong><\/p>\n\n\n\n<p><strong>SQL Server is built to handle set-based operations efficiently. To filter data based on a condition, use a single SELECT statement with appropriate indexing:<\/strong><\/p>\n\n\n\n<p><strong>SELECT *<br>FROM TableName<br>WHERE Criteria = 0; &#8212; Assuming Criteria is a binary or Boolean column<\/strong><\/p>\n\n\n\n<p><strong>Optimizations for Large Datasets<\/strong><\/p>\n\n\n\n<p><strong>If performance is a concern for large datasets, consider these optimizations:<\/strong><\/p>\n\n\n\n<p><strong>Indexing:<\/strong><\/p>\n\n\n\n<p><strong>Ensure there is an index on the Criteria column to speed up filtering.<\/strong><\/p>\n\n\n\n<p><strong>Partitioning:<\/strong><\/p>\n\n\n\n<p><strong>Partition large tables to distribute data and improve query performance.<\/strong><\/p>\n\n\n\n<p><strong>Query Hints:<\/strong><\/p>\n\n\n\n<p><strong>Use query hints like OPTION(RECOMPILE) if parameter sniffing is an issue.<\/strong><\/p>\n\n\n\n<p><strong>Batch Processing:<\/strong><\/p>\n\n\n\n<p><strong>If you need to process the data incrementally, use batch processing instead of row-by-row loops:<\/strong><\/p>\n\n\n\n<p><strong>WHILE EXISTS (SELECT 1 FROM TableName WHERE Criteria = 0)<br>BEGIN<br>DELETE TOP (1000)<br>FROM TableName<br>WHERE Criteria = 0;<br>END;<\/strong><\/p>\n\n\n\n<p><strong>Summary<\/strong><\/p>\n\n\n<div class=\"block-core-list\">\n<ul class=\"wp-block-list\">\n<li><strong>Avoid loops for filtering data in SQL Server; use set-based queries instead.<\/strong><\/li>\n\n\n\n<li><strong>Optimize performance with indexing, partitioning, and batch processing if necessary.<\/strong><\/li>\n\n\n\n<li><strong>Row-by-row processing should be a last resort for edge cases where set-based logic cannot be applied.<\/strong><\/li>\n<\/ul>\n<\/div>\n\n\n<p><strong>This approach aligns with SQL Server&#8217;s strengths and ensures better performance, simplicity, and maintainability.\u201d<\/strong><\/p>\n<\/div>\n<\/div>\n\n\n\n<p>Ok, so it is clearly better than my advice, but really, it ignored the meat of my poor code. The advice is more or less correct (some assumptions like Criteria is a bit or integer value), but also subtly different than other advice it had given me, which is always a concern because why would it give different advice for the same input?<\/p>\n\n\n\n<p>For example, it goes on to talk about deletes for some reason, when I was only talking about a <code>SELECT<\/code> statement.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-explaining-my-cruddy-code\">Explaining my cruddy code<\/h3>\n\n\n\n<p>Last thing I will try is to just ask it to explain my terrible code. So I put in the following prompt:<\/p>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:60px\"><\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<p>\u201cExplain this code: <br>CREATE TEMP TABLE #Results<br><br>WHILE (RowsStillInTable)<br>BEGIN<br>INSERT INTO #Results<br>SELECT TOP 1 *<br>FROM TableName<br>WHERE Criteria = False;<\/p>\n\n\n\n<p>IF @@RowsCount = 0<br>Break;<br><br>WEND; \u201c<\/p>\n<\/div>\n<\/div>\n\n\n\n<p>This gave quite a reply. Let\u2019s look at the replies:<\/p>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:60px\"><\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<p><strong>\u201cCreating a Temporary Table<\/strong><\/p>\n\n\n\n<p><strong>CREATE TEMP TABLE #Results<\/strong><\/p>\n\n\n\n<p><strong>This line attempts to create a temporary table named #Results. However, there is a syntax error here:<\/strong><\/p>\n\n\n\n<p><strong>In SQL Server, the correct syntax is CREATE TABLE #Results, not CREATE TEMP TABLE.<\/strong><\/p>\n\n\n\n<p><strong>Temporary tables (prefixed with #) exist only for the duration of the session or batch in which they are created. They are often used to store intermediate results.\u201d<\/strong><\/p>\n<\/div>\n<\/div>\n\n\n\n<p>Yep, guilty! However, I am also guilty of not providing columns or returning the results in the loop, which it failed to note. One thing I am starting to note is that it doesn&#8217;t seem to really dig into multiple facets of incorrectness, but if it gives one that is really great.<\/p>\n\n\n\n<p>Continuing into the reply:<\/p>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:60px\"><\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<p><strong>\u201cThe WHILE Loop<\/strong><\/p>\n\n\n\n<p><strong>WHILE (RowsStillInTable)<br>BEGIN<\/strong><\/p>\n\n\n\n<p><strong>This is the start of a WHILE loop that is supposed to run as long as the condition (RowsStillInTable) is true.<\/strong><\/p>\n\n\n\n<p><strong>However, <code>RowsStillInTable<\/code> is not a valid SQL Server construct, and this part of the code is incorrect or incomplete. Typically, the condition would need to be a Boolean expression, such as checking if ows still exist in the source table.\u201d<\/strong><\/p>\n<\/div>\n<\/div>\n\n\n\n<p><\/p>\n\n\n\n<p>Something to notice here. Be careful if you are using this to look at something that includes pseudocode (especially if it isn&#8217;t labeled as such. It doesn\u2019t realize that this could be just saying to check for rows in the table. I didn\u2019t enumerate that, so this is good stuff too.<\/p>\n\n\n\n<p>Sometimes I find it taking <code>RowsStillInTable<\/code> as a Boolean value (which SQL Server doesn\u2019t support), or as an integer, but never did it consider that it might just be pseudocode.<\/p>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:60px\"><\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<p><strong>\u201c3. Inserting Rows Into the Temporary Table<\/strong><\/p>\n\n\n\n<p><strong>INSERT INTO #Results<br>SELECT TOP 1 *<br>FROM TableName<br>WHERE Criteria = False;<\/strong><\/p>\n\n\n\n<p><strong>This statement inserts a single row (TOP 1) from TableName into the temporary table #Results where the Criteria column has the value False (or 0, depending on data type).<\/strong><\/p>\n\n\n\n<p><strong>The TOP 1 modifier limits the result to just one row, but without an ORDER BY clause, the row returned is arbitrary and not deterministic.\u201d<\/strong><\/p>\n<\/div>\n<\/div>\n\n\n\n<p>Here is the first really big failure in checking this code. \u201cwhere the Criteria column has the value False (or 0, depending on data type)\u201d there is no way in SQL Server for the value to have a value False without quotes. \u2018False\u2019 can be translated to 0 in some cases, but not typically like this. This will work:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">SELECT CASE WHEN CAST(1 as bit) ='True' THEN 1 ELSE 0 END,\n\t   CASE WHEN CAST(0 as bit) ='True' THEN 1 ELSE 0 END,\n\t   CASE WHEN CAST(1 as bit) ='False' THEN 1 ELSE 0 END,\n\t   CASE WHEN CAST(0 as bit) ='False' THEN 1 ELSE 0 END<\/pre>\n\n\n\n<p>And return 1, 0, 0, 1, respectively, but remove the quotes around True or False and you will get an error:<\/p>\n\n\n\n<p><code>Msg 207, Level 16, State 1, Line 4<\/code><br><code>Invalid column name 'False'.<\/code><\/p>\n\n\n\n<p>Continuing into the reply:<\/p>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:60px\"><\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<p><strong>\u201cChecking the Number of Rows Inserted<\/strong><\/p>\n\n\n\n<p><strong>IF @@RowsCount = 0<br>    Break;<\/strong><\/p>\n\n\n\n<p><strong>@@ROWCOUNT is a system function that returns the number of rows affected by the last statement.<\/strong><\/p>\n\n\n\n<p><strong>Here, it checks if the previous INSERT INTO operation inserted zero rows. If no rows were inserted, the loop exits using the BREAK statement.\u201d<\/strong><\/p>\n<\/div>\n<\/div>\n\n\n\n<p><\/p>\n\n\n\n<p>Hey something that works correctly as I wrote it. Who saw that coming? That won&#8217;t last long.<\/p>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:60px\"><\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<p><strong>\u201cEnd of the WHILE Loop<\/strong><\/p>\n\n\n\n<p><strong>WEND<\/strong>;<\/p>\n\n\n\n<p><strong>WEND is not valid SQL Server syntax. The correct keyword to close a WHILE loop in SQL Server is END.<\/strong><\/p>\n\n\n\n<p><strong>The corrected version would look like this:<\/strong><\/p>\n\n\n\n<p><strong>WHILE (condition)<\/strong><\/p>\n\n\n\n<p>BEGIN<\/p>\n\n\n\n<p><strong>&#8212; Loop body<\/strong><\/p>\n\n\n\n<p><strong>END;\u201d<\/strong><\/p>\n<\/div>\n<\/div>\n\n\n\n<p>Interestingly, IT wrote pseudocode by using (condition), but never considered my pseudocode\u2026<\/p>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:60px\"><\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<p><strong>\u201cKey Issues in the Code<\/strong><\/p>\n\n\n\n<p><strong>Syntax Errors:<\/strong><\/p>\n\n\n\n<p><strong>CREATE TEMP TABLE should be CREATE TABLE #Results.<\/strong><\/p>\n\n\n\n<p><strong>WEND should be replaced with END.<\/strong><\/p>\n\n\n\n<p><strong>Inefficiency:<\/strong><\/p>\n\n\n\n<p><strong>This code processes rows one at a time, which is inefficient for large datasets.<\/strong><\/p>\n\n\n\n<p><strong>A SELECT statement with appropriate filtering is more efficient.<\/strong><\/p>\n\n\n\n<p><strong>Lack of Determinism:<\/strong><\/p>\n\n\n\n<p><strong>The TOP 1 query lacks an ORDER BY clause, which may lead to inconsistent results.<\/strong><\/p>\n\n\n\n<p><strong>Unclear Loop Condition:<\/strong><\/p>\n\n\n\n<p><strong>The condition (RowsStillInTable) is undefined and would not work in SQL Server.\u201d<\/strong><\/p>\n<\/div>\n<\/div>\n\n\n\n<p>Mostly true stuff. I don\u2019t think <code>TOP 1<\/code> with an <code>ORDER BY<\/code> technically provides determinism exactly, as data can change while you are looping. You would need to use a temporary table or even a static cursor for that.<\/p>\n\n\n\n<p>But the description mostly makes sense. And I will give it a pass since I didn\u2019t provide a reasonable use case for using a loop here.<\/p>\n\n\n\n<p>Finally, some advice, but with a bit of a mistake:<\/p>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:60px\"><\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<p><strong>\u201cA Correct and Efficient Approach<\/strong><\/p>\n\n\n\n<p><strong>If the goal is to process or filter rows from a table, use a set-based query instead of a loop:<\/strong><\/p>\n\n\n\n<p><strong>SELECT *<br>INTO #Results<br>FROM TableName<br>WHERE Criteria = 0;<\/strong><\/p>\n\n\n\n<p><strong>This query filters all rows meeting the condition (Criteria = 0) and inserts them into the temporary table in a single operation.\u201d<\/strong><\/p>\n<\/div>\n<\/div>\n\n\n\n<p>But if you send them to a temp table, this query basically does nothing. Especially when I said this loop did the same thing as my simple <code>SELECT<\/code> statement.<\/p>\n\n\n\n<p>It also takes my pseudocode of <code>= False<\/code> and assumes I am using a bit, which is a more forgivable rewrite that I may have done myself.<\/p>\n\n\n\n<p>And the final advice:<\/p>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:60px\"><\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<p><strong>\u201d Conclusion<\/strong><\/p>\n\n\n\n<p><strong>The provided code is syntactically and conceptually flawed for SQL Server. To process data efficiently:<\/strong><\/p>\n\n\n\n<p><strong>Use set-based operations wherever possible.<\/strong><\/p>\n\n\n\n<p><strong>Avoid row-by-row logic unless absolutely necessary.<\/strong><\/p>\n\n\n\n<p><strong>Fix syntax errors like CREATE TEMP TABLE and WEND.\u201d<\/strong><\/p>\n\n\n\n<p><\/p>\n<\/div>\n<\/div>\n\n\n\n<p>Generally, makes sense, except for the fact that I asked: \u201cExplain this code\u201d, not \u201cTell me what is wrong with it philosophically\u201d<\/p>\n\n\n\n<p>What it needed to note was something such as:<\/p>\n\n\n\n<p>\u201cThis code appears to be trying to load data into a temporary table #Results. There may be a better way to do this using the following code: <br>SELECT *<br>INTO #Results<br>FROM TableName<br>WHERE Criteria = 0;<\/p>\n\n\n\n<p>Then perhaps break down the code, tell me the syntax issues, and preach at me that row by row logic is bad.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-document-telling-us-we-are-looking-at-bad-advice\">Document Telling Us We are looking at bad advice<\/h2>\n\n\n\n<p>My last test was to basically admit that the body of the article was completely garbage. I changed it into a \u201chere is bad advice to not follow\u201d kind of article. So I altered the document to start out as:<\/p>\n\n\n\n<p>\u201cI asked many SQL Server administrators for the absolute dumbest advice they have ever been given by real people recently and this (perhaps a bit too humorous) article is the culmination of what I was told. The advice ranges from horrible to the extremely horrible, but none of it could be considered useful whatsoever.\u201d<\/p>\n\n\n\n<p>What I want to know here is whether it pays attention well to the header and judges accordingly. So, I again ask: \u201cPlease review the following document in terms of technology\u201d and paste in the document. The reply is kind of spot on (and you can read the entire <a href=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2025\/02\/LLM-Technical-Editor-Test-\u2013-ChatGPT_Results-1-Admitting-The-Advice-is-Wrong.txt\">reply here<\/a>):<\/p>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:60px\"><\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<p><strong>\u201cReview of &#8220;Really Bad Advice for SQL Server Administrators&#8221; (Technological Perspective)<\/strong><\/p>\n\n\n\n<p><strong>This document is clearly a satirical piece aimed at highlighting poor practices in SQL Server administration. While humorous, its tone may be misinterpreted by novice readers as genuine advice. Below, I address key points raised in the article and provide a brief explanation of why each is bad practice, supported by technical reasoning.\u201d<\/strong><\/p>\n<\/div>\n<\/div>\n\n\n\n<p>Ignoring that it says &#8220;I address key points&#8221; like the computer from 2001 A Space Odyssey, the replies in each section basically ignores the fact that this is satire. If it knows that, it the advice should show that. It should give advice how to keep the satirical edge, but not lead people astray.<\/p>\n\n\n\n<p>For comparison, the row by row processing section now says:<\/p>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:60px\"><\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<p><strong>\u201cRow-by-Row Processing (RBAR) Instead of Set-Based Operations<\/strong><\/p>\n\n\n\n<p><strong>Why This is Bad: Row-by-row processing is significantly slower than set-based operations, as SQL Server is optimized for set-based query execution.<\/strong><\/p>\n\n\n\n<p><strong>Best Practice: Write queries that operate on sets of data rather than iterating through rows.\u201d<\/strong><\/p>\n<\/div>\n<\/div>\n\n\n\n<p>Which is of course good advice, but it really isn&#8217;t a good section compared to what I was trying to do and include code. (Which it still doesn&#8221;t mention.)<\/p>\n\n\n\n<p>Finally:<\/p>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:60px\"><\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<p><strong>\u201cConclusion<\/strong><\/p>\n\n\n\n<p><strong>The document is an effective humorous critique of common SQL Server mismanagement practices. However, it risks misinterpretation if taken literally. The importance of adhering to best practices\u2014such as maintaining security, scalability, and performance\u2014cannot be overstated.<\/strong><\/p>\n\n\n\n<p><strong>Suggestion: Add a clear disclaimer at the beginning, emphasizing that the advice is intentionally bad and should not be followed. This will help ensure the content is understood as satire.\u201d<\/strong><\/p>\n<\/div>\n<\/div>\n\n\n\n<p>I mean, it isn\u2019t really \u201csatire\u201d per ce, it was framed as just bad advice that had been<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-conclusion\">Conclusion<\/h2>\n\n\n\n<p>So far, reasonably good. It is not nearly as good of an editor as a human would be, and it made a few mistakes. But I feel like I have answers my first question \u201cWill it refute the advice clearly?\u201d Not only did it refute the advice, but it called me out on my less than subtle advice.<\/p>\n\n\n\n<p>I think it is clear that after I do this same test with Copilot, I need to refine the concept and be less overt with the advice and be more subtle with my errors. Code that fails for simple reasons. Compatibility levels, typos, invalid semicolons. Advice that is weak but true.<\/p>\n\n\n\n<p>In fact, that is kind of why I did this series of tests to begin with. I commonly find that these tools I am testing say \u201cthis is a good paper\u201d but I find some obvious concerns that are missed. I want to know that overall, at least, it is catching the gist of the paper and general correctness.<\/p>\n\n\n\n<p>Either way, my concerns have somewhat been allayed. This tool definitely did not try to make it out like this was good advice, and it did a good job even with the reverse piece that said explicitly that this was bad advice.<\/p>\n\n\n\n<p>I especially liked that is said \u201cWhile humorous, its tone may be misinterpreted by novice readers as genuine advice.\u201d I actually did not include the entire fake articles as posts for that very reason, and even zipped them up so they hopefully will not be read by the search engine.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>As started in part 1 of this series, I have set out to test an LLMs ability to technical edit. For my first set of tests, I am using a pair of articles I created, filled with very bad advice. The advice is the same for both articles, but what differs is the intro and&#8230;&hellip;<\/p>\n","protected":false},"author":56085,"featured_media":105430,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[2],"tags":[159075,159261,147000],"coauthors":[19684],"class_list":["post-105418","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-blogs","tag-ai","tag-louisdavidson_llmtechediting","tag-tech-editing"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/105418","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/users\/56085"}],"replies":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/comments?post=105418"}],"version-history":[{"count":10,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/105418\/revisions"}],"predecessor-version":[{"id":105431,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/105418\/revisions\/105431"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/media\/105430"}],"wp:attachment":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/media?parent=105418"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/categories?post=105418"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/tags?post=105418"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/coauthors?post=105418"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}