Opinion: Non-responsive contact forms are worse than none at all

Marketing folk have a few common truisms. One is that it costs way less to keep a customer than it is to find a new one. I have no doubt that's true. It's important to keep existing customers. And it costs a lot to get new ones.

For many people now, your website will be the first point of contact. By the time that someone visits your website though, a lot of things often have already had to go right. So it's really important to keep them once they get there. Why waste all that?

One of the real challenges though is that although most websites have contact forms, very, very few of them actually lead to a response.

Worse, many company sites are now intentionally pretty much hiding all their phone numbers, email addresses, etc. and require you to fill in contact forms. Yet I've lost count of how many times I've filled in a contact form at a website, and never heard another thing from that company.

That's ridiculous. 

Turns out, I'm not alone. I recently read a review that talked about a survey they did where they completed sales response forms on 100 websites, and ended up with contact back from less than 20.

That means that either:

  • The request form doesn't actually work i.e. it doesn't actually send a message to anyone who cares
  • The request is going to someone who is either overwhelmed or unable to respond for some reason
  • The request is going to the person who manages the website and who is uninvolved in the actual business.

So a quick check for today:

Do the contact methods on your website actually work?

Do they work on mobile devices?

If someone completes a contact form, are they likely to end up with a response?

T-SQL 101: #40 String data types in SQL Server

You'll notice when we discuss strings that there are many data types compared to what we had with numbers:

char was the original data character data type. By fixed length, I mean that if it's defined as 10 characters long, it always returns 10 characters, even if there are only 5 characters stored in the string.

Prior to SQL Server 2019, char could only be used with ANSI characters (i.e. single byte characters). From 2019 onwards, char can also be used to store multi-byte characters by using UTF-8 encoding. I'll write more about that another day.

nchar was the same thing except that it stored multi-byte characters to allow it to work with the full Unicode character set. Originally these were only 2 bytes per character, but in SQL Server 2012, an option for 4 byte characters was also added.

varchar and nvarchar are the variable length versions of char and nchar. When you select data from them, they only return the characters that are stored i.e. if there are 5 characters stored in an nvarchar(10) string, when you query it, you only get 5 characters back.

Originally, Sybase had a text data type that was used for long ANSI characters, and so it became part of SQL Server too. It allowed up to 2GB of data in a single value. ntext was the Unicode equivalent.

Nowadays, you shouldn't use text or ntext, and should use varchar(max) or nvarchar(max) instead.

Learning T-SQL

It's worth your while becoming proficient in SQL. If you'd like to learn a lot about T-SQL in a hurry, our Writing T-SQL Queries for SQL Server course is online, on-demand, and low cost.

Learning Mandarin: What is stroke order and does it matter?

I was at school a long time ago. For all the 5 years that I was at high school, I studied Japanese. In Brisbane in 1971 when I started studying it, I can tell you that doing so was a rare thing. In fact, studying any Asian language was pretty rare. The country has come a long, long way since those days.

Curiously though, my Japanese teacher wasn't Japanese. He was a Caucasian guy named Joe Geiger. He must have been almost the least popular teacher in the school. Teachers were free to terrorise students in those days, and he had made doing that into nearly an art form. But his soft spot was Japanese and South East Asian Studies. Because I took those two subjects, and because I continued them both on for the full five years (the latter was only offered after-school hours for the last four years), I ended up getting on really well with Joe and learned a lot from him. That made me a bit of an oddity (a bit like a teacher's pet) in his other classes.

Stroke Order

In Japanese class though, one thing that struck me early on, was his insistence on writing characters with the correct stroke order. At first, I didn't get why it mattered. And it's the same story in Chinese and other languages. I'm not across Korean (yet) but my guess is that it matters there too.

Here's an example. The Chinese character for word I (i.e. referring to myself) is:

我  (Wǒ) which is pronounced a bit like "war" with a descending and ascending tone in the middle of the word.

Here's how it's drawn:

There are several reasons why this stroke order matters:

Your characters don't look as good if you don't draw them in the correct order. There's a natural flow to how the characters are drawn, and you won't get the right angles, etc. if you draw them in the wrong order.

Because they flow, they're actually easier to write in the first place. They're designed for elegant movement of the brush (or now the pen).

Tools that recognise writing work far better when you use the right order. That matters if you're ever trying to use handwritten input on a program.

And the strangest reason of all: people watching you write will think you are uneducated. I'm not joking. Incorrect stroke order is a giveaway for a lack of education.

Tools for Learning Stroke Order

The best tool (by far) that I've found for learning this is called Skritter. It can teach both Chinese and Japanese handwriting and tones. It's a subscription-based application, and its mobile applications (i.e. iOS) are excellent.

While I can get by without too much handwriting, I find that when you practice it, it totally reinforces your understanding of the characters and words of the language.

I'm determined to spend more time on Skritter this coming year.

Learning Mandarin

I'll write more soon on the best methods for learning Mandarin. If you want to get a taste for it in the meantime though, my current favorite site is iTalki, and my favorite teacher by far is Amy He. If you decide to try it, click here and it's cheaper for both you and me.

Snowflake for SQL Server Users – Part 11 – GET, PUT and SnowSQL for working with local files

In a previous post, I talked about stages. They are internal or external cloud storage locations that you can use the COPY command to copy data into database tables from or use the COPY command to export data from database tables.

Now if you are using external stages, they're just standard storage accounts in AWS (S3), Azure Storage, or Google (GCS). You can use whatever tools you want to get files from other locations (like your local file system) to/from these accounts.

But if you want to get data in or out of the internal stages, you need to talk to the Snowflake API. While you could write your own code to do that, the easiest way to do that is by using a tool called SnowSQL.


Snowflake has a number of connectors. SnowSQL runs on 64bit versions of Windows, macOS, and Linux. It's built using the Snowflake Connector for Python. That connector is just straight Python coding. On Windows, for Python v2, you need 2.7.9 or higher. For Python v3, you need 3.5.0 or higher.

SnowSQL is a command line client that you can run interactively as a shell, or you can run in batch mode. Commands can be referenced via a -f parameter (common on Windows) or redirected into it via stdin (common on Linux and macOS).

Using SnowSQL is very much like using OSQL or SQLCMD. Like SQLCMD though, it has a rich command language of its own with variables, auto-complete, command line history, and variable substitution.

SnowSQL Commands

You can run SQL commands through SnowSQL but most people would use other tools for that. The commands that most people will use SnowSQL for are the GET and PUT commands. These are not SQL commands but SnowSQL commands.

GET is used to retrieve files from the internal stages.

PUT is used to upload files into the internal stages.

Other useful (and related) commands are:

LIST is used to list the files in either internal or external stages.

REMOVE is used to delete files from the internal stages.





SQL: How to find primary key column names in SQL Server

Another question that I answered on a forum recently was about how to find the primary key column (or columns) for a table.

Here's an example of the code required:

I hope that helps someone.

SDU Tools: List content items in the SQL Server Reporting Services catalog

I mentioned last week that I've been needing to write queries against the SQL Server Reporting Services catalog. I often need to list the items that are contained in the SSRS catalog.

So, in our free SDU Tools for developers and DBAs, we added a procedure that does just that. It's called RSListContentItems.

It takes two optional parameters:

@RSDatabaseName sysname – the name of your SSRS database

@IsOrderedByUserName bit – should the output be ordered by user name?

The database name will default to ReportServer which is the name that SSRS uses during install if you don't change it.

Find out more

You can see it in action in the main image above, and in the video here:

Access to SDU Tools is one of the benefits of being an SDU Insider, along with access to our other free tools and eBooks. Please just visit here for more info:



Opinion: Are tools like Grammarly really safe to use?

When I first saw Grammarly appear, I thought "what a great idea".

I signed up for an account and started using it, and really liked what it did for my writing. It seemed to work well, although it got seriously messed up sometimes. It really didn't like it when I had a bunch of code on the screen. Overall though, I liked it.

But then one of my security-focused friends asked me:

Do you really want a browser extension that takes everything that you type and sends it to their servers for review? 

And when I stopped and thought about it, that's really the last thing that makes sense to me from a security point of view. The problem is that the browser has no idea about what's OK to send to the extension and what it shouldn't.

Who knows what they do with all the data that's sent to them?

I read their privacy policy and there are a lot of gray areas in there. But the bigger problem is that there's a bunch of data that I just don't want sent in the first place.

Now I could use the icon in the browser toolbar and keep turning it on and off but that's not going to happen because I'll forget to do it when I should.

I think what I'd like to see is just an option where I could highlight a chunk of text, right-click it, and say "Analyze at Grammarly". I could be OK with that.

Would love to hear what you all think. Comment here or ping me offline.

T-SQL 101: #39 Numeric operators in SQL Server

Today, I'm continuing the discussion on the variety of data types supported by SQL Server. I'll round out the discussion by looking at the operators that are used with the numeric data types. Here are the operators:

Some of these are fairly obvious but even then, they can have hidden complexity.

We use the plus sign + to add numbers, and we use the minus sign (or dash) – to subtract numbers. No surprise there.

Multiplication uses the asterisk * and is also easy enough. However, keep in mind that when you use multiplication, you probably should also be thinking about rounding if you are working with decimal values, and not just integers.

When you multiply an integer by a decimal, the result is promoted to being a decimal (i.e. the higher data type).

Division uses the slash / sign. What confuses most people is how it applies to data types. For example, what would you expect to see output from this query:

SELECT 10 / 4;

If you said 2.5, you wouldn't be alone, but you'd also be wrong. It would output the value 2.

When you divide an integer by an integer, the result is an integer, not a decimal.  Now if you executed this instead:

SELECT 10.0 / 4.0;

you would see 2.5 as the answer. A decimal divided by a decimal returns a decimal.

But what would happen to this one:

SELECT 10 / 4.0;

Again, you'd get 2.5 as the answer. An integer divided by a decimal will return the higher data type i.e. a decimal.

Finally, the % sign is the modulo operator. You can think of modulo as the remainder after a division. So this query:

SELECT 10 % 3;

would return the value 1. That's because as integers, 10 divided by 3 is 3, with a remainder of 1.

Learning T-SQL

It's worth your while becoming proficient in SQL. If you'd like to learn a lot about T-SQL in a hurry, our Writing T-SQL Queries for SQL Server course is online, on-demand, and low cost.

Learning Mandarin: Chinese belief in luck

I need to start by coming right out and saying that I don't believe in things being lucky or unlucky. Many things that appear to have come from luck just haven't. Sometimes things go the way you hope, and other times they don't go the way you hope. And bad things can just happen for no good reason. What you can do is put yourself in a position where you increase your chances of a good thing happening. That's making your own luck.

I think that a belief in things being lucky or not, grew from an age when we just understood far less about how the world works. The rituals followed by cargo cults are a great example.

Belief in luck in Asian Cultures

However, in Chinese culture (and in most Asian cultures), there is a deep-seated belief in luck, and it's reflected all through superstitions and in the language.

I've previously described why you'll have a hard time selling a house numbered 4 to a Chinese person, and even harder time selling one numbered 24.

And there are so many actions that are considered lucky or unlucky:

  • Throwing baby's teeth that have fallen out on the roof (good luck)
  • Washing or cutting your hair the last or first day of the year (bad luck)
  • Giving someone a clock as a present (bad luck)
  • Clip your nails at night (bad luck for inviting ghosts to that place)
  • Keeping pet turtles (bad luck for slowing down fortune)
  • Sweeping during New Year (bad luck for sweeping away fortune)
  • Red color (lucky)

Now the Chinese are not alone on this. Many westerners hold strong superstitions as well. I remember the time I put shoes on a table when I was young. The problem wasn't dirt (they were brand new shoes); the problem was my father's belief that it brings death.

Literally translated, luck is 运气 (Yùnqì).

The first character 运 (Yùn) has a number of meanings, and one is related to luck. The second character (Qì) usually relates a bit to gas or spirit.

The down side

Awesome image by Macau Photo Agency

丰富 (Fēngfù) means rich or plentiful and you'll often see it shown in casinos and gambling places that Asian people frequent.

As a final note, I should add that this continuing belief in luck has a dark side as well. Gambling addiction is very prevalent in Asian cultures. Casinos here in Australia and in other countries make no secret that their top market is "Asian High Rollers".

Learning Mandarin

I'll write more soon on the best methods for learning. If you want to get a taste for it in the meantime though, my current favorite site is iTalki, and my favorite teacher by far is Amy He. If you decide to try it, click here and it's cheaper for both you and me.

Snowflake for SQL Server Users – Part 10 – Working with file formats

One thing that I quite like about Snowflake is the way it cleanly works with a wide variety of file formats.

Obviously this changes over time but at the time of writing, you could COPY from the following source file formats:

  • CSV
  • JSON
  • AVRO
  • ORC
  • XML

There are also quite a number of options for configuring how these are used. Apart from the obvious options like record and field delimiters, skipping rows, etc, one of the most important of these options is compression. You can currently choose these options for compression:

  • AUTO
  • GZIP
  • BZ2
  • ZSTD
  • NONE

I had good outcomes using the AUTO setting. Mostly I'm using zip'd input files.

There are a few options for transforming data while loading it, but they are very limited. For example, you can alias a column or change its position.

Named File Format

Similar to the way you can avoid specifying full file locations every time by creating an external stage, you can avoid specifying all your file format details every time by creating a named file format.

No surprise, that's done with the CREATE FILE FORMAT command.

Data Export

When you export data, you again use the COPY command, but currently there are less file format options available than there are for input. You can use:

  • CSV
  • JSON

I would be surprised if the others aren't added soon.