Generating Random Strings with GenAI

One of the things I’ve been experimenting with in AI is taking things other people do and seeing how well the AI works. In this case, I took a Prompt from Louis and tried to see how well it worked. This post describes the results from a few models.

This is part of a series of experiments with AI systems.

The Challenge Using Claude

Louis was using an AI to generate some test data to play with the new Regex functionality in SQL Server 2025. He put this in ChatGPT: “create a set of random string data with 1000 rows for a sql server table named RegExTest. It should insert data into a column named Value”.

He had mixed results with ChatGPT, which I tend not to use. Instead, I tried this in Claude. I like Claude as I get an explanation separate from the code. Here’s a view of the page:

2025-06_line0031

Here’s the code, which is nice because I could steal certain patterns out of here if I had the need. The explanation was also good, and I’ve reproduced that here:

<start claude explanation>

This SQL script creates 1000 rows of diverse random string data for your RegExTest table. The data includes various patterns that are useful for testing regular expressions:

  • Email addresses (user@domain.com)
  • Phone numbers ((123) 456-7890)
  • Dates (MM/DD/YYYY)
  • Mixed alphanumeric with special characters (ABC-123_XYZ)
  • Numeric strings (123456)
  • URL patterns (https://www.example.com/path)
  • Code patterns (AB12C345)
  • Words with spaces (Hello World)
  • Mixed case strings (AbCdEf123)
  • Random alphanumeric strings

The script uses a recursive CTE to generate 1000 rows and applies different string generation patterns based on the row number modulo operations. This ensures you get a good variety of data types to test your regular expressions against.

The script also includes table creation (if it doesn’t exist) and verification queries to confirm the data was inserted successfully.

<end claude explanation>

There was an issue in the else part of the CASE. The last CONCAT call only had the first parameter and CONCAT needs two parameters, so I copy/pasted the 2nd parameter from the last THEN statement, which worked fine. In this case, that parameter was an acceptable choice to create a random alpha string.

Perplexity

I got a very weak result from Perplexity. Essentially, write insert statements, though you could use a script.

2025-06_line0037

I didn’t see a script, so I asked. I got this.

2025-06_line0039

Here’s the SQL Code:

2025-06_line0040

That’s weak. It works, but it’s weak and I think I could have written that in not much more time than the AI took.

It did end with this sentence: Let me know if you want the script in another format or with different string lengths!

I did and then got a series of different scripts for different formats, but each was producing a separate 1000 rows of only that format.

DeepSeek

I download the DeepSeek coder model and decided to try that. The basic prompt was disappointing. The model basically wanted to use Python and only imported modules without other code.

2025-06_line0041

When I said that and asked for code, I got more details, but with the script separated out into sections. The top seemed to repeat a bit.

2025-06_line0042

Then I got each part of the script.

2025-06_line0043

I didn’t run this, but it’s a reasonable way to do things for developers. For data people, this seems like overhead.

I asked for SQL, and got a script for Oracle, but more interesting, the code is for 1000 rows, but the comments say ten thousand. Can’t the GenAI count?

2025-06_line0044

I asked to change this to SQL Server and got this code.

2025-06_line0045

I don’t know what to say except that I’m disappointed in the local deepseek model, which is not only slow, but hasn’t produced a good answer.

Summary

Claude clearly wins this experiment.

Posted in Blog | Tagged , , | Comments Off on Generating Random Strings with GenAI

Heading to SQL Bits 2025

I’ll be at SQL Bits tomorrow, Saturday Jun 20, 2025 for the final day of the conference. I wasn’t selected to speak, but since I’m in Cambridge next week I came a couple of days early to stop by the event.

As this publishes, I’m probably just about to land at Heathrow and I am looking forward to a fairly quiet day in London.

Tomorrow should be fun. I have lightly looked at the schedule and I see a few AI sessions that might be fun to watch, but mostly I’m looking forward to catching up with friends.

If you see me, please don’t hesitate to say hi.

Posted in Blog | Tagged , , | Comments Off on Heading to SQL Bits 2025

SQL Server 2025 Excitement

Are you looking forward to SQL Server 2025? Or perhaps you think this is just another release, or perhaps you are not looking for new features or capabilities in your environment. Maybe you don’t care about new things, but are looking for enhancements to features introduced in 2017/2019/2022. There is certainly no shortage of things that can be improved from previous versions (cough graph *cough).

I ran across an article on the five things that one person is looking forward to in SQL Server 2025. It’s a good list, and the things included make me consider an upgrade. Certainly, any improvements in the performance area, especially with all the investments made in Intelligent Query Processing over the last few versions, are worth evaluating. They might help your workload, or they might not, but if they do, then upgrade.

However, test, test, test. I can’t stress that enough. Test with your workload, not some random queries. Spend some time setting up WorkloadTools or find some other way to replay a set of queries from multiple clients to see if performance improves. It’s far too easy to look at a query in isolation and make a snap decision. With a load, sometimes performance looks different.

The HA improvements are also enticing, especially the idea of offloading backups more easily. Of course, this means you need to ensure you can and know how to, restore a complex set of backups in an emergency situation. Distributed systems are complex, and backups from multiple nodes (remember, you might get unexpected failovers) are a distributed system. Make sure you consolidate those, and plan for potential disruptions if your backup system/share/location is gone. Local backups are always nice, but Murphy’s law might cause you problems in multiple ways with multiple nodes and backups moving across them.

Again, test, test, test, and consider weird situations taking place. They will occur, and you should ensure your staff has a simple way to deal with them.

We’ve had a few SQL Server versions that leaped forward. SQL Server 2005 changed the paradigm, and I think SQL Server 2016 was another time of dramatic growth. Will SQL Server 2025 be one of those versions, or is it one that has a few incremental improvements?

Let me know your thoughts today.

Steve Jones

Listen to the podcast at Libsyn, Spotify, or iTunes.

Note, podcasts are only available for a limited time online.

Posted in Editorial | Tagged | Comments Off on SQL Server 2025 Excitement

Better Trigger Design: #SQLNewBlogger

I had someone ask me about using triggers to detect changes in their tables. This is the third post in the series. The first one

Another post for me that is simple and hopefully serves as an example for people trying to get blogging as #SQLNewBloggers.

The Setup

We’re using the same table from the first post.  This is the dbo.Customer table with a PK and 5 other fields. Here is the data in the table:

2025-05_0231

I had this trigger in the last post, and showed how it captured updates to the ContactEmail field.

CREATE OR ALTER TRIGGER Customer_tru ON dbo.Customer FOR UPDATE
AS
BEGIN
     IF UPDATE(CustomerName)
         INSERT dbo.logger (logdate, logmsg) VALUES (DEFAULT, 'dbo.Customer.CustomerName changed')
     IF UPDATE(AddressKey)
         INSERT dbo.logger (logdate, logmsg) VALUES (DEFAULT, 'dbo.Customer.AddressKey changed')
     IF UPDATE(CustomerStatus)
         INSERT dbo.logger (logdate, logmsg) VALUES (DEFAULT, 'dbo.Customer.CustomerStatus changed')
     IF UPDATE(CustomerContact)
         INSERT dbo.logger (logdate, logmsg) VALUES (DEFAULT, 'dbo.Customer.CustomerContact changed')
     IF UPDATE(ContactEmail)
     BEGIN
         INSERT dbo.logger (logdate, logmsg)
         SELECT GETDATE(), 'ContactEmail updated from ' + d.ContactEmail + ' to ' + i.ContactEmail
          FROM inserted i
          INNER JOIN Deleted d ON i.CustomerID = d.CustomerID
     END
END

This seemed to work, but did it really?

The Problem

Let’s illustrate the big problem with this change. I’ll run this code:

UPDATE dbo.Customer
  SET ContactEmail = ‘andy@sqlservercentral.com’
  WHERE CustomerID = 2;

If I do this, here are the results:

2025-05_0232

I get a NULL? Why, the original value is null and when I concatenate null with other values, I get NULL. Not ideal.

Let’s fix this problem. I’ll use a function to handle null values. Note, I need to do this for both the inserted and deleted tables. Here’s the new trigger.

CREATE OR ALTER TRIGGER Customer_tru ON dbo.Customer FOR UPDATE
AS
BEGIN
     IF UPDATE(CustomerName)
         INSERT dbo.logger (logdate, logmsg) VALUES (DEFAULT, 'dbo.Customer.CustomerName changed')
     IF UPDATE(AddressKey)
         INSERT dbo.logger (logdate, logmsg) VALUES (DEFAULT, 'dbo.Customer.AddressKey changed')
     IF UPDATE(CustomerStatus)
         INSERT dbo.logger (logdate, logmsg) VALUES (DEFAULT, 'dbo.Customer.CustomerStatus changed')
     IF UPDATE(CustomerContact)
         INSERT dbo.logger (logdate, logmsg) VALUES (DEFAULT, 'dbo.Customer.CustomerContact changed')
     IF UPDATE(ContactEmail)
     BEGIN
         INSERT dbo.logger (logdate, logmsg)
         SELECT GETDATE(), 'ContactEmail updated from ' + COALESCE(d.ContactEmail, 'null') + ' to ' + COALESCE(i.ContactEmail, 'null')
          FROM inserted i
          INNER JOIN Deleted d ON i.CustomerID = d.CustomerID
     END
END

We can see this handles the null appropriately.

2025-05_0233

In this case I’ve chosen to replace a NULL value with the word ‘null’. This means something to me, but I could have just as well replaced this with “blank” or any other word. In many applications a developer might display a null value as a blank, so choose what works for you.

I’m also including an example to show this works for multiple rows. Here I’ll update multiple rows and we can see each is inserted into my log.

2025-05_0234

This is a good reason to audit certain activities, as people will sometimes make these mistakes and updates lots of data.

This trigger is slightly more useful, and handles the NULL cases, but it still isn’t perfect. Imagine I need to parse out changes, or generate the reverse transactions, or even search for certain changes. Stuffing a lot of data into a single field is overloading it, and making it less useful over time. What we’d really want to do is separate pertinent data into different fields. In a NoSQL world, we might do this by using a JSON schema to track the before and after.

We could do that here, just stuff JSON into the log message and read it back out and de-serialize it.

SQL New Blogger

This post modified our trigger to address a previous design problem: not handling nulls. We also showed how to test the trigger with multiple rows. This shows I’ve added knowledge to my skillset and can test what I’m trying to do.

Write your own blogs that might examine what you’ve done poorly in the past and how to fix the problems you’ve identified, even in simple code. Many of us do this a lot.

This was a 20-30 minute post for me. You could likely do it in a similar amount of time.

Posted in Blog | Tagged , , | 1 Comment