What’s the worst that could happen?

Mistakes happen. They’re not always acceptable.

Pressing 'DELETE' key

Pressing 'DELETE' key...

What’s the worst that could happen? Your entire table being deleted without confirmation.

Prevention is simple. Use a text query. And do a

SELECT COUNT(*) FROM veryimportanttable WHERE ... ; DELETE FROM veryimportanttable WHERE ... 

Understanding Spam

The first step to defeating your enemy is to know them. Read more about what spam is, how it works, and how it’s done.

How Spam Works

Your email address is worth 1 cent. If it’s known that a living being is behind the address, it’s worth more. And if it’s advertising likes and dislikes are known, it’s worth around 20 cents. Of course, one email address is not going to do a spammer much good. Instead, they buy, sell, and harvest millions of email addresses at a time.

Unsubscribing to a legitimate email should be just that, but unsubscribing from a spam mail only means that there is a human who reads spam at that address. Men are 50% more likely to buy things from spam than women, which explains why so much of it are products for males. It’s also worth noting that it’s easier for a spammer to continue sending emails to non-existant, dead, or blocking addresses rather than to detect this and cease sending them.

Spam Email

Phising Spam Sample

Phising Spam Sample

With modern day aggressive spam detection that can automatically direct spam into the trashcan without the user ever seeing it or even prevent it from reaching an email address at all, spammers have also stepped up their game. They no longer use words easily detectible by bayesian (self-learning) spam filters such as male and female anatomical parts, and instead use ones that convey the same idea – ‘member’, for example. Other techniques involve using pictures, not including hyperlinks, adding books or quote text, or even including random garbage in the email to all try to avoid the recipient’s spambin. It doesn’t matter if the resulting email has misspellings, grammar errors, or makes no sense, because users are likely to read curious looking emails. What makes spam so easy is that it can all be done from a program that automates sending different email messages from a template to a plethora of unfortunate email addresses with a single click of a button.

Phising is also a common technique. It’s all too easy to fake sender email addresses, url links, and content, especially since so few people know to examine email headers for validity.


A botnet is a group of large compromised computers (usually in the thousands) used for spam mail sending and other malicious purposes. Botnets are either rented from other hackers or simply stollen. Botnets have made past headlines for sending massive amounts of spam ( Rustock Botnet Responsible for 39% of All Spam)

From The Spammer’s Perspective

It’s all too easy (watch a video of xrumer in action) to get started into the spam business, which is centered around our modern culture of instant gratification. $1,000 will buy 1 million email addresses, and referral sites will usually offer a portion of the sales (25%-50%). From there, a mass-mailer can be aquired for little cost, and mass-mailed in a matter of minutes. Of course, if the employment source decides not to pay up, there’s little a spammer can do. To avoid authorities and taxes, spammers employ money laundering techniques.

Product Buyer’s Pricetag Referral Profit Profit for 0.0001% of Sales to 1 Million Email Addresses
Male Parts Enhancer $300 25-50% %7,500-15,000
Online Casino $100 25%-50% $2,500-5,000

Forum and Blog Spam

Forum and blog spam works much the same way that email spam does, only with different guardians: spam blockers like Askimet and services like Captcha. Spammers obtain lists of sites by buying them, crawling for popular software, or simply by human inclusion. Forums simply employ captchas and other human validation techniques like logic puzzles, pictures, honey pots, and timing the form submission time to prevent spambot signups and posting. Since most forums and blogs use the same names for fields, automatic form fillers can easily generate random names and emails, and even register and validate spam email accounts.

Captchas and Other Validation

Some spambots can solve logic puzzles while most others have employed optical recognition (OCR) to crack traditional captchas and picture-puzzles. But that’s not all – spammers also have a black market for outsourcing to better captcha breaking services, or even to human solvers for as low as $1 per thousand captchas. With human crackers, a screenscraper is employed to send a copy of the image to the cracker’s screen who then types in the answer and sends it back.

Stack Overflow's Re-Captcha

Stack Overflow's Re-Captcha

GitHub Accidentally Wipes Their Database : How to Do Customer Service the Right Way

Sunday, Nov 14, during a testing session, GitHub accidentally mis-configured their test plans and ended up deleting their entire production database (full article).

How did they receive 100+ comments saying ‘No worries, mate. Keep up the good work.’ ? With good customer service. Notice how they did it.

They publicly announced their blunder, summarizing what happened for tl;dr readers and with a fully-detailed explanation for all who cared to read. They got things straightened out, set up a plan and schedule for the remainder of what needed to be corrected, and announced what they are doing to prevent this situation. And notice what they didn’t do – make excuses, pass blame, or hide the situation.

Talk about excellent customer service. When’s the last time you deleted a database and didn’t receive angry calls and emails?


ASP.NET: Scrolling (Or Not), On Demand

I make quite a few ‘fast and dirty’ web applications where the application needs validation, or there are other post backs involved.

EASY: With MaintainSrollPositionOnPostback
Set the ‘MaintainScrollPositionOnPostback’ to ‘true’ to keep the page from scrolling (or, if not specified, defaults to ‘false’). So for example, if it is set to ‘true’ and there is a postback, the page will not be scrolled. (With the exception of built-in Validators throwing validation errors).

<%@ Page Title="" Language="C#" AutoEventWireup="true" MaintainScrollPositionOnPostback="true" %>

With JavaScript
I found a neat little snippet to scroll the page when the submit button is clicked. Built-in Valdiators cause the page to jump to the top when the user tries to submit but the form is not complete. But custom validation in your code does not, so the user doesn’t see these messages and thinks the form is broken when they press ‘submit’ but nothing happens. You could build your own validators, but hey, who has time for that …

<asp:Button ID="uxSubmit" runat="server" Text="Submit Form" OnClick="submit_Click" OnClientClick="window.scroll(0,0);" />

HARDER: With UpdatePanels
Use AJAX UpdatePanel’s to contain the piece of code that should not scroll while you do postbacks. Make sure that events fire the postbacks properly, etc. The less code the UpdatePanel contains, the faster it will reload (so wrapping the entire page is generally not a good idea). Keep in mind that usually clicking Button’s inside of UpdatePanels is buggy (try using LinkButton instead). These come with ASP.NET 3.5, but if you have 2.0 you can reconfigure your web.config to allow them.

Ruby: Parse error: Unexpected kEnd

This error usually indicates that somewhere you forgot an ‘end’ or close-brackets ‘}’ . But not always. It can also indicate other things like problems during execution.

If any sort of loop iteration, control conditional (the ‘e’ in if (e) … ), or control block (the {} in if (e) {…} ) has a problem, it can cause this inaccurate error, masking the real problem , even if all the other iterations are fine, Debug carefully.

myarray.each { |element|
if ( conditionalmightthrowanerror )

Ruby can also display this kEnd behavior because Ruby doesn’t always “recognize” if statements with a single line beneath (compared to if (condition) {block} end ). Like this:

if myvariable==true

Just add an ‘end’ or braces around your block to fix it.

HTML Lists : Lettered, Roman Numeral, …

Your HTML list doesn’t have to have an ugly bullet. They can be lettered (A, B, C) or numbered (1, 2, 3) instead. Additionally, you can set the starting list index (the starting number).

<ul> : Standard unordered, bulleted list
<ol> : An ordered list ( • , •, • , … )
<ol type=”1″> : Numbered, ordered list. (Default) ( 1, 2, 3, … )
<ol type=”A”> : Ordered List via capital letters ( A, B, C, … )
<ol type=”a”> : Lower-case letters ( a, b, c, … )
<ol type=”I”> : Capital roman numerals ( I, II, III, … )
<ol type=”i”> : Lower case roman numerals ( A, B, C, … )
<ol type=”1″ start=”21″ > : Starts list at 21 ( 21, 22, 23, … )
<ol type=”A” style=”font-weight: bold;”> :  Bold letters ( A, B, C, … )
<ul style = “list-style-image: url(http://bit.ly/dcH4Ea)”> Change your bullets inline ( , , , … )

Area51 : How to gain a high reputation


StackExchange has a new component, called http://area51.stackexchange.com/. It’s a special place for Q&A site proposals. As reputation points can only be gained from a proposal in the Definition phase, i’ll focus on that below.

High Reputation Strategies

Link Your Accounts

If you have a StackOverflow, SuperUser, Meta, or ServerFault account, you can link them together via option in your profile to gain a quick jump in points.

Understand How The System Works

Lastly, it is important that you understand exactly how Area51 works – so read those FAQs and About page. For example, both on-topic and off-topic example questions can net you points, while Not-A-Good-Example questions will loose you points. I frequently browse through Meta to see any new developments or discussions – like asking poster to use the format “How do [H2O] and [HO] differ?”. It’s also important to understand how the unwritten system works – for example, proposing an example question that’s already been listed is not looked favorably upon, will often be voted Not-A-Good-Example, and you will loose points.

Do Your Math

If you’re serious about your reputation, you have to be stingy about it and monitor it carefully, just like a credit rating. The last thing you want is for all of your hard-earned points to be quickly leaking away into questions netting you negative reputation. So, it’s important to do your math. Remember, both Off-Topic, and On-Topic votes will rep you +10 rep. Not-A-Good-Example gives you -2. When the Not-A-Good-Example points begin to turn negative, you should delete it quickly, just as one would toss a decaying vegetable. Example : One off-topic and one Not-A-Good-Example will net you +10-2=+8 points, so this question is worth keeping.

Fastest Gun In The West

There is a “problem” on the SO/SU/SF/M sites called the “Fastest Gun in the West” problem, and it goes like this : the first user to submit an answer often gains the most points (unless the answer is incorrect). This exists on Area51 as well. Remember, you cannot gain points on questions if you haven’t submitted them.

Suggest Example Questions to All Proposals – Especially New Ones

To gather points, you should suggest your 5 example questions for as many proposals as you can – even if you know nothing about it. Google for FAQs on the proposal’s topics if you are unsure for some sure-fire point-catchers.  New proposals are Fastest-Gun-In-The-West bait. I’ve often submitted questions for new, seemingly bad proposals that have gained me hundreds of points and a few badges. So, watch for those new proposals. Remember, new proposals have less existing questions to read through, so it is faster and easier to suggest new ones.

Repetitive Popular Questions Are Good

There are certain kinds of questions that are common to most all proposals, and will certainly net you points. Figure out what they are, and how to use them, for easy gains. Here are some to get you started : “What’s your favorite [proposal related thing] ?” , “How do [thing A] and [thing B] differ?” , “What’s the best [proposal related thing] for [proposal related thing] ?” , “How do I [ proposal related thing ] ?”

MySQL / ASP.NET Stored Procedure Caching

Symptoms of Stored Procedure Caching

You update your sproc & code accordingly, but the page gives you an error asking for old, deleted parameters. The error looks like this :

System.ArgumentException: Parameter ‘deleted_parameter_foo_bar’ not found in the collection. at MySql.Data.MySqlClient.MySqlParameterCollection …

What is MySQL Stored Procedure Caching?

Normally, stored procedure caching is a good thing. It saves the MySQL server some time and work by storing the execution plan for future use instead of recreating it all over again every time. However, as in above, it can also be a great pain.The key thing to know about it is:

Every single connection to the MySQL server maintains it’s own stored procedure cache. (The Art of SQL)

What this means for you is that refreshing your browser, re-executing your CREATE PROCEDURE command, etc, all won’t work.

How to Check if Caching is On

Execute this MySQL query:

SHOW VARIABLES LIKE 'query_cache%'

How To Fix It?

Here’s what will and won’t fix the problem:

Won’t Fix:

  • Restarting your browser
  • Using a different browser
  • Restarting your (not-the-server) computer
  • HttpResponse.RemoveOutputCacheItem(“./folder/page.aspx”); (in ASP.NET code-behind)
  • Delete & re-upload the problematic files
  • Further updating, deleting, re-creating the stored procedure on the server

Will Fix:

  • Deleting & re-uploading the entire ASP.NET application (or web.config or global.asax). It forces it to re-compile on the server, clearing the connection’s cache.
  • Executing RESET QUERY CACHE on the MySQL server to clear the cache
  • Restarting the MySQL server or MySQL server computer

As you can see, the first option, to simply re-upload web.config, global.asax, or the entire web app, is the simplest, safest, and most viable solution for developers with limited MySQL server permissions.

Disable PK/FK Contraints For Easier Data Migration

If you are copying mass amounts of data, doing updates, or moving data, Primary and Foreign keys can get in the way.

You can disable them like so :

USE [Northwind]

exec sp_MSforeachtable 'ALTER TABLE ? DISABLE TRIGGER ALL'  

And then remember to re-enable them later.

USE [Northwind]

exec sp_MSforeachtable 'ALTER TABLE ? CHECK CONSTRAINT ALL'  
exec sp_MSforeachtable 'ALTER TABLE ? ENABLETRIGGER ALL'  

MySQL Stored Procedures

MySQL stored procedures are available, but not frequently used. It’s more common to see SQL in the code, especially with PHP.

MySQL has an odd stored procedure format and it looks like this :


CREATE DEFINER=`myDatabase`@`%` PROCEDURE `myProcedure`
/* optional parameters here */
IN variable1 TYPE,
OUT variable2 TYPE

/* body here */

  DECLARE myVariable TEXT;

  IF (boolean expression) THEN
    /* stuff */
    /* stuff */

  SELECT MyTextColumn INTO myVariable FROM myTable WHERE ... ;

END $$


MySQL Gotcha’s

It’s important to note that all DECLARE’s inside of the procedure body must be located above/before any code. Unlike MSSQL, strict ‘;’ semi-colon end-line delimiters are enforced. You cannot specify input/output parameter default values like you can in MSSQL.

The MySQL query editor will only execute the first line of any query, so if you wish to do anything multiline, you will need to use a script or procedure/function. Highlighting text and pressing TAB will not tabulate the line but replace with tab spacing instead. In the query table editor, you may not move columns around (but you can remake the table and/or drop/recreate columns).

Select statement assignment is possible, and do-able in a quick and easy way without cursors (see code).

There are now many differences between MS SQL and MySQL datatypes, so be sure to do your reading. For example, a MySQL VARCHAR column can hold up to 255 characters, and anything more needs to be stored in a TEXT datatype. Integer(#) does not specify the number of digits (something else). There is no BOOLEAN/BIT in MySQL. There are two time/date types, DATESTAMP, and TIMESTAMP.

In a table, you may not specify a default time/date for DATESTAMP like Now(), but you may specify up to a single TIMESTAMP column to have a default of CURRENT_TIMESTAMP.

Perhaps not quite as much of a Gotcha as the others, your Syntax Errors are now akin to LaTeX (Badness on line … ), “You have an error in your MySQL syntax, check the manual that corresponds to your MySQL version for the right syntax to use near’ <100 characters of problematic line>'”