<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Discrete Information &#187; SQL</title>
	<atom:link href="http://www.discreteinformation.com/tag/sql/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.discreteinformation.com</link>
	<description>Providing a finite amount of information.</description>
	<lastBuildDate>Sun, 23 Aug 2009 03:42:50 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>SQL Injection Attacks on the Rise</title>
		<link>http://www.discreteinformation.com/2009/08/sql-injection-attacks-on-the-rise/</link>
		<comments>http://www.discreteinformation.com/2009/08/sql-injection-attacks-on-the-rise/#comments</comments>
		<pubDate>Sun, 23 Aug 2009 03:35:28 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[Injection Attacks]]></category>

		<guid isPermaLink="false">http://www.discreteinformation.com/?p=79</guid>
		<description><![CDATA[According to a recent article at Dark Reading, SQL injection attacks are on the rise. Surprisingly it’s not due to a new technique, increasing success, or great ingenuity. Instead, it’s just old standby methods being used in great numbers due to simplicity and the possibility of valuable results.
Source:  Tech Insight: SQL Injection Demystified, Dark [...]]]></description>
			<content:encoded><![CDATA[<p>According to a recent article at <a href="http://www.darkreading.com">Dark Reading</a>, SQL injection attacks are on the rise. Surprisingly it’s not due to a new technique, increasing success, or great ingenuity. Instead, it’s just old standby methods being used in great numbers due to simplicity and the possibility of valuable results.</p>
<p>Source: <a href="http://www.darkreading.com/database_security/security/app-security/showArticle.jhtml?articleID=219401046"> Tech Insight: SQL Injection Demystified</a>, Dark Reading</p>
]]></content:encoded>
			<wfw:commentRss>http://www.discreteinformation.com/2009/08/sql-injection-attacks-on-the-rise/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Ten Things to Help SQL Beginners</title>
		<link>http://www.discreteinformation.com/2009/06/ten-things-to-help-sql-beginner/</link>
		<comments>http://www.discreteinformation.com/2009/06/ten-things-to-help-sql-beginner/#comments</comments>
		<pubDate>Fri, 12 Jun 2009 02:19:22 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[Jet]]></category>

		<guid isPermaLink="false">http://www.discreteinformation.com/?p=71</guid>
		<description><![CDATA[In a recent post at TechRepublic, some beginner SQL tips were listed. They include definitions and examples for DISTINCT, GROUP BY, various aggregate functions, and other basic commands. The article focuses on Jet, but many tips apply to other SQL products too.
Source: 10+ tips for working smarter with SQL, TechRepublic
]]></description>
			<content:encoded><![CDATA[<p>In a recent post at <a href="http://www.techrepublic.com">TechRepublic</a>, some beginner SQL tips were listed. They include definitions and examples for <code>DISTINCT</code>, <code>GROUP BY</code>, various aggregate functions, and other basic commands. The article focuses on <code>Jet</code>, but many tips apply to other SQL products too.</p>
<p>Source: <a href="http://blogs.techrepublic.com.com/10things/?p=796">10+ tips for working smarter with SQL</a>, TechRepublic</p>
]]></content:encoded>
			<wfw:commentRss>http://www.discreteinformation.com/2009/06/ten-things-to-help-sql-beginner/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Paging Stored Procedure in MS SQL, By Page</title>
		<link>http://www.discreteinformation.com/2009/05/ms-sql-server-paging-method-1/</link>
		<comments>http://www.discreteinformation.com/2009/05/ms-sql-server-paging-method-1/#comments</comments>
		<pubDate>Sun, 24 May 2009 19:31:39 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[MS SQL]]></category>
		<category><![CDATA[Pagination]]></category>

		<guid isPermaLink="false">http://www.discreteinformation.com/?p=15</guid>
		<description><![CDATA[MS SQL has the TOP clause, and it works very similar to MySQL&#8217;s LIMIT clause. However, the TOP clause in MS SQL provides no sort of OFFSET equivalent. Thus the TOP clause is virtually useless for a proper paging control. Let&#8217;s see one way we can work around that limitation:
For reference, here are the CREATE [...]]]></description>
			<content:encoded><![CDATA[<p>MS SQL has the <code>TOP</code> clause, and it works very similar to MySQL&#8217;s <code>LIMIT</code> clause. However, the <code>TOP</code> clause in MS SQL provides no sort of <code>OFFSET</code> equivalent. Thus the <code>TOP</code> clause is virtually useless for a proper paging control. Let&#8217;s see one way we can work around that limitation:</p>
<p>For reference, here are the <code>CREATE</code> and <code>INSERT</code> statements for the <code>[users]</code> table used in this example.</p>
<pre>
CREATE TABLE [users] (
  user_id INT PRIMARY KEY,
  username VARCHAR(16),
  password VARCHAR(16),
  email VARCHAR(128)
);

INSERT INTO [users] (user_id, username, password, email)
SELECT 1, 'bob', 'bob!password', 'bob@gmail.com'
UNION ALL
SELECT 2, 'john', 'john!password', 'john@yahoo.com'
UNION ALL
SELECT 3, 'kim', 'kim!password', 'kim@msn.com'
UNION ALL
SELECT 4, 'rachel', 'rachel!password', 'rachel@aol.com'
UNION ALL
SELECT 5, 'frank', 'frank!password', 'frank@email.com';
</pre>
<p>Now, let&#8217;s create a stored procedure to search our <code>[users]</code> table. It takes three paramaters. The <code>@email</code> paramater is a full or partial e-mail to search. <code>@page</code> is the page to be displayed, and <code>@per_page</code> is the number of results per page.</p>
<pre>
CREATE PROC searchUsersByEmail
  @email VARCHAR(128),
  @page SMALLINT,
  @per_page SMALLINT
AS

SET @last_page = (@nbr_results - 1) / @per_page + 1;

SELECT
  @nbr_results = COUNT(*)
FROM [users] AS u
WHERE u.email LIKE '%' + @email + '%';

SET @last_page = @nbr_results / @per_page; 

IF (@page = 1)
BEGIN
  -- Special first page case:
  SELECT TOP (@per_page)
    u.user_id,
    u.username,
    u.email
  FROM [users] AS u
  WHERE u.email LIKE '%' + @email + '%'
  ORDER BY u.email ASC;
END;
ELSE IF (@page = @last_page)
BEGIN
  -- Special last page case:
  SELECT s0.*
  FROM (
    SELECT TOP (@nbr_results - (@last_page - 1) * @per_page)
      u.user_id,
      u.username,
      u.email
    FROM [users] AS u
    WHERE u.email LIKE '%' + @email + '%'
    ORDER BY u.email DESC
  ) AS s0
  ORDER BY s0.email ASC;
END;
ELSE IF (@page > @last_page)
BEGIN
  -- Error / Empty set case, replace with error if desired.
  SELECT
    u.user_id,
    u.username,
    u.email
  FROM [users] AS u
  WHERE 1 = 0;
END;
ELSE
BEGIN
  -- All other cases:
  SELECT s1.*
  FROM (
    SELECT TOP (@per_page) s0.*
    FROM (
      SELECT TOP (@page * @per_page)
        u.user_id,
        u.username,
        u.email
      FROM [users] AS u
      WHERE u.email LIKE '%' + @email + '%'
      ORDER BY u.email ASC
    ) AS s0
    ORDER BY s0.email DESC
  ) AS s1
  ORDER BY s1.email ASC;
END;
</pre>
<p>Now let&#8217;s test our search procedure by searching for all e-mails with &#8220;.com&#8221;:</p>
<pre>
[searchUsersByEmail] @email = '.com', @page = 1, @per_page = 3;

user_id     username email
----------- -------- ----------------
1           bob      bob@gmail.com
5           frank    frank@email.com
2           john     john@yahoo.com

[searchUsersByEmail] @email = '.com', @page = 2, @per_page = 3;

user_id     username email
----------- -------- ----------------
3           kim      kim@msn.com
4           rachel   rachel@aol.com
</pre>
<p>That&#8217;s it. Now you have a functional procedure in MS SQL as an alternative to MySQL&#8217;s <code>LIMIT x OFFSET y</code> clause.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.discreteinformation.com/2009/05/ms-sql-server-paging-method-1/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>
