Posts Tagged ‘SQL’

Accessing SQLite database in a Django application

Monday, July 25th, 2011

I’ve been building some apps in Django lately. The apps are fairly small and Django comes with what is pretty much out of the box support for SQLite. While I love the ORM built in data management in Django, during development I often find myself needing to visually view the contents in my database, and if necessary quickly make updates.

So I started looking around and found a pretty cool free app called SQLite Database Browser. While it’s got a few bugs, I really admire the simplicity of the application. When it really comes down to it, I want to be able to view the data cleanly and quickly. Sometimes I will want to update, delete, or insert data. And the very few times that I would want to perform DBA tasks, I’m going to handle that via other means anyways. I found that viewing data is quick and simple. Setup is also very simple. If working locally, just open your db file in your project.

The one bug I found that is pretty annoying concerns creating records. If the table contains fields that are not nullable it becomes impossible to perform inserts via the GUI interface. This pretty much means that you can never really create anything. It appears that in the preferences you can assign a default for non-nullable value that will allow record creation. Only problem is that this preference doesn’t seem to work. I set the preference, close the dialog, reopen the dialog and the preferences are no longer set. Doesn’t seem to be saving or something. Overall, works very well with SQLite databases.

Using cfqueryparam list attribute when using ‘IN’ operator

Wednesday, January 12th, 2011

When writing SQL in Coldfusion where the ‘IN’ operator is used you will have to use the list attribute of the cfqueryparam tag, and if using a delimiter other than a comma will need to include the ‘separator’ attribute to indicate the delimiting character.  This, of course, only applies if the list of available values are stored externally in a variable.  Let’s take a look at how to use the ‘IN’ operator in Coldfusion and some varying scenarios that either will or will not work.

First: Using actual values (works)

<cfset variables.dsn = "cfartgallery" />

<cfquery name="variables.selectArt" datasource="#variables.dsn#">
	SELECT *
	FROM art
	WHERE artName IN ('Morph','Things','Ideas')
</cfquery>

(more…)

Setting up a read-only DSN in Coldfusion

Monday, January 3rd, 2011

In the case that you may be worried about database availability due to heavy stress on reporting queries, you may be considering data replication/streaming, if your specific database provider offers such a service (like Oracle’s Data Replication capabilities), to use for read-only reporting. This method helps ensure the availability of the database when data manipulation needs to occur. However, trying to write to a read-only database will, of course, bomb out.

Fortunately, Coldfusion offers a very easy way to guarantee that the read-only database is only used for SELECT statements. To begin with, both the writable database and the read-only database will need their own datasources set up in the CF Administrator.

(more…)

Performing arithmetic with SQL or Coldfusion

Saturday, September 18th, 2010

I’ve been running through some online courses concerning Oracle systems.  One of the earlier lessons discusses performing arithmetic with your SQL statement so that not just the data in the table is returned, but manipulated table data is returned as well.  This peaked my interest since it’s so simple, and yet I’ve never really considered using SQL to do basic arithmetic work from within the SQL statement as opposed to just manipulating the base values with Coldfusion.

Just out of curiosity I ran some tests on my local system, which of course doesn’t run Oracle, but does run MySql.  The test consists of the idea that a company has a database of job applications, but after 30 days they want them to be marked as expired.  So essentially what I want to end up with is an application date plus 30 days, and then compare if that date is greater than today’s date.  All we want to potentially use the database for is adding the 30 additional days to each date in the database.  Because I didn’t have any data to work with I used the following function to enter 500 dummy records into MySql.

<cffunction name="buildQuery" displayname="Build Query" hint="Needed to build a simple set of tables with applications and creation dates." access="public" output="false" returntype="void">

	<cfoutput>
		<cfloop from="1" to="500" index="i">
			<cfset var startDate = dateFormat(now()) />
			<cfset var endDate = dateFormat(now() - 365) />

			<cfset var randomDate = randRange(startDate, endDate) />

			<cfquery name="insertApps" datasource="apps">
				INSERT INTO application_tbl (application_created)
				VALUES (#randomDate#)
			</cfquery>
		</cfloop>
	</cfoutput>

</cffunction>

This function simply takes a random date between now and one year ago and inserts it into the application_tbl table. Now we have some data to process with Coldfusion and SQL. The two functions that return the same thing, but one use CF and the other SQL are.

<!--- Process with Coldfusion --->
<cffunction name="processWithCF" displayname="Process with Coldfusion" hint="Processes the expiration date with Coldfusion" access="public" output="false" returntype="array">

	<cfset var appsQuery = getQuery() />
	<cfset var appsAry = arrayNew(1) />
	<cfset var finalDate = "" />

	<cfloop query="appsQuery">
		<cfset finalDate = application_created + 30 />

		<cfset arrayAppend(appsAry, dateFormat(finalDate, "full")) />
	</cfloop>

	<cfreturn appsAry />

</cffunction>

<cffunction name="getQuery" displayname="Get Query" hint="Gets a query full of applications and dates created." access="private" output="false" returntype="query">

	<cfset var thisQuery = "" />

	<cfquery name="thisQuery" datasource="apps">
		SELECT *
		FROM application_tbl
	</cfquery>

	<cfreturn thisQuery />

</cffunction>
<!--- Process with SQL --->>
<cffunction name="processWithSQL" displayname="Process with SQL" hint="Processes the expiration date with SQL" access="public" output="false" returntype="array">

	<cfset var appsQuery = getQueryProcessed() />
	<cfset var appsAry = arrayNew(1) />

	<cfloop query="appsQuery">
		<cfset arrayAppend(appsAry, dateFormat(application_created, "full"))>
	</cfloop>

	<cfreturn appsAry />

</cffunction>

<cffunction name="getQueryProcessed" displayname="Get Query" hint="Gets a query full of applications and dates created." access="private" output="false" returntype="query">

	<cfset var thisQuery = "" />

	<cfquery name="thisQuery" datasource="apps">
		SELECT application_id, application_created + 30 AS application_created
		FROM application_tbl
	</cfquery>

	<cfreturn thisQuery />

</cffunction>

The only difference between the two is that with the function getQueryProcessed() the SQL statement returns ‘application_created + 30 AS application_created’. This is returning a date created 30 days later than the actual date created. In the getQuery() function the statement is returning the raw data, but I am then using Coldfusion ‘finalDate = application_created + 30′ to set the date to 30 days in advance of the actual date.

In order to time the processing of both simple formats I use the following index page which outputs the average processing time for both according to 1000 iterations over both methods. The index page that monitors performance is the following.

<!--- set of lists to keep up with each time of processing --->
<cfset variables.cfProcessingList = "" />
<cfset variables.sqlProcessingList = "" />

<cfset VARIABLES.process = createObject("component", "processExpiration").init() />

<cfset variables.startCount = getTickCount() />

<cfloop from="1" to="1000" index="variables.i">
	<cfset VARIABLES.processedWithCF = VARIABLES.process.processWithCF() />
</cfloop>

<cfset variables.endCount = getTickCount() />

<!--- time to process and output instance --->
<cfset variables.processingTime = variables.endCount - variables.startCount />

<!--- append processing time to list --->
<cfset variables.cfProcessingList = listAppend(variables.cfProcessingList, variables.processingTime, ",") />

<cfset variables.startCount = getTickCount() />

<cfloop from="1" to="1000" index="variables.i">
	<cfset VARIABLES.processedWithSQL = VARIABLES.process.processWithSQL() />
</cfloop>

<cfset variables.endCount = getTickCount() />

<!--- time to process and output instance --->
<cfset variables.processingTime = variables.endCount - variables.startCount />

<!--- append processing time to list --->
<cfset variables.sqlProcessingList = listAppend(variables.sqlProcessingList, variables.processingTime, ",") />

<!--- average processing times --->
<cfset variables.cfProcessingAvg = arrayAvg(listToArray(variables.cfProcessingList, ",")) />
<cfset variables.sqlProcessingAvg = arrayAvg(listToArray(variables.sqlProcessingList, ",")) />

<cfoutput>
	<br /><br /><br />
	CF Processing Average: #variables.cfProcessingAvg#<br /><br />
	SQL Processing Average: #variables.sqlProcessingAvg#
</cfoutput>

The results:
Average Coldfusion processing time – 23509 ms
Average SQL processing time – 34163 ms

Considering that this was 1000 iterations we’re talking marginal differences at best. As such, when I see two ways of performing the same process that takes roughly the same amount of time to process, I immediately begin looking at design. This is an instance where I do feel the context in which this type of performing is needed should determine the method that is used. Nonetheless, with my experience I think the majority of the time using Coldfusion to perform the data manipulation portion is best practice.

I say this because what does take time are database connections and the process of calling data from a database. Let’s take our theoretical example above and say that we want to not only see which applications are being thrown away, but also those that would be thrown away if our cutoff was 60 days old and 90 days old. To do this the really bad way, we would write three different SQL statements, each adding 30, 60, and 90 days to each returned result. A much better way of doing it would be to return each set within the same SQL statement so that we are only making one database call. This statement would look like:

SELECT application_id, application_created + 30 AS application_created_thirty, application_created + 60 AS application_created_sixty, application_created + 90 AS application_created_ninety
FROM application_tbl

Even better and more flexible is to simply return the data with SQL and then use Coldfusion to do all data manipulation. It will simply run faster and be more flexible to change easily over time. An abstract function can be written that adds a passed in number to a passed in value and returns the result. This doesn’t restrict us to statements. The abstract function could look like the following.

<cffunction name="addStuff" displayname="Add Stuff" hint="Adds any passed in number to any passed in value and returns it." access="public" output="false" returntype="Numeric">

	<cfargument name="value" displayname="Value" hint="Value to add to." type="numeric" required="true" />
	<cfargument name="toBeAdded" displayname="To Be Added" hint="Number to be added to value." type="numeric" required="true" />

	<cfset var result = ARGUMENTS.value + ARGUMENTS.toBeAdded />

	<cfreturn result />

</cffunction>

Now after returning the raw data from the database the above function can be used for manipulation as such.

<cfset VARIABLES.result1 = addStuff(application_created, 30) />
<cfset VARIABLES.result2 = addStuff(application_created, 60) />
<cfset VARIABLES.result3 = addStuff(application_created, 90) />

The beauty of this is that we can continue to add to it simply and quickly. Let’s say our boss came to us and wanted to see how many applications would be left under 45 and 50 days old. We would just add to our code:

<cfset VARIABLES.result4 = addStuff(application_created, 45) />
<cfset VARIABLES.result5 = addStuff(application_created, 50) />

So this is how I see it. There are probably situations where it would make sense to process arithmetic with SQL, but for the most part I feel performing data manipulation with Coldfusion is the way to go. Nonetheless, having the ability to do these things with SQL alone is certainly a powerful tool to have in one’s arsenal.

Mapping a table using ORM in Coldfusion 9

Saturday, March 13th, 2010

I’ll assume here that you have already set ORM in your Application.cfc.  If not you may want to check out the post on setting up ORM in the Application.cfc file first.  If you have the Application file all set and you have a database then you’re ready to map out a database table.

For this example I’ll be using MySql as the database with a table called ‘stores_tbl’.  It has three fields that we need to worry about.  The first is the ‘store_id’ (the primary key), the ‘store_name’, and the ‘store_link’.

We’ll need three files to make this work.  First is the Application.cfc file, which again I’m assuming is already set up.  Second is a .cfm file that will output our data objects.  And third is the persistent cfc that will map to the ‘stores_tbl’.  I’ve created a directory called ‘orm_mappings’ under my root directory to hold all my persistent cfcs.   You can also create a directory if you like.  When the application loads Coldfusion searches through the application looking for any persistent cfcs and maps them accordingly.  So technically you could organize your persistent cfcs any way you wish as long as they are inside the application using ORM.

Let’s take a look at our persistent cfc.

stores_tbl.cfc

<cfcomponent displayname="Stores Table" hint="ORM mappings to the stores_tbl" output="false" persistent="true">

	<!--- SET PRIMARY KEY COLUMN --->
	<cfproperty name="id" column="store_id" ormtype="integer" generator="native">

	<!--- SET OTHER COLUMNS --->
	<cfproperty name="store_name" ormtype="string">
	<cfproperty name="store_link" ormtype="string">

</cfcomponent>

First thing to note here is the name of the cfc. It is named the same as the table name it is mapping to. So our table name is ‘stores_tbl’ and the name of the cfc is ‘stores_tbl.cfc’. The name of the cfc will indicate to Coldfusion where the mapping is to take place. Next is the ‘persistent=”true”‘ attribute in the ‘cfcomponent’ tag. This indicates to coldfusion that this is an ORM mapping and not a standard cfc.

(more…)

Setting up ORM in Coldfusion 9

Saturday, March 13th, 2010

First things first, you will need a database and Coldfusion 9 for this to work.  Once you have  these two things you’ll need to create your Application.cfc file.

Remember in Coldfusion 8 using the THIS scope at the top of the component outside of any functions to set things like the name of the application, the session management, and the application timeout.  Well, now you need to add to that list a few new settings in the THIS scope.  You’ll need to add THIS.ormenabled = true and THIS.datasource = “yourdatasource”.

So our very simple Application.cfc file will look like the following.

Application.cfc

<cfcomponent displayname="Application File" hint="Application File" output="false">

	<!--- SET UP ORM --->
	<cfset THIS.name = "applicationTest">
	<cfset THIS.datasource = "datasource">
	<cfset THIS.ormenabled = true>

</cfcomponent>

Keep in mind that setting the datasource in the THIS scope is the same thing you did in Coldfusion 8 when you would set the datasource in the tag. Point being that this datasource is pretty useless without setting up the datasource in the Coldfusion Administrator first. Take a look at Setting up a datasource to learn more about this.  The really freakin awesome thing about this though is that setting the datasource here sets it globally across your application, which means for every call to the database you do not need to specify the datasource.  This is a big deal in my book.

So ORM should be all set in your application.

DISCLAIMER** This is a record of what I’m learning in ORM in Coldfusion 9. While what I post should work, I lay no claim to best practices. My hope here is that other ORM beginners like myself may benefit from this information on the assumption that their path to learning ORM might be similar to my own. To learn more about ORM by those who know more than myself check out (of course) the adobe docs and a couple very nice presentations on cfmeetup.com by Raymond Camden and Bob Silverberg.

Using jQuery, AJAX, and Coldfusion to filter SQL results

Sunday, March 7th, 2010

The following post will explain the logic behind the ‘live’ search results that are becoming more and more popular on the web.  The idea is that you have a record set at hand ready to be searched as a user types into an input box what they are looking for.  While in traditional software programming this has never been a huge deal, the request/response nature of the web makes our lives as web developers a little more difficult.  To bypass the request/response model we let the searching happen via the client using AJAX.

For this example three files will be needed.  The client file (the file with the filter tool and search results), a javascript file to handle the AJAX and jQuery output, and a Coldfusion component to handle the data processing.  I’ve set up a demo here to check out so you’ll know what we’ll be building.

Let’s take a look at the client file first.

jquery_result_filter.cfm

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<!--- PROXY --->
<cfajaxproxy cfc="path.to.jquery_result_filter" jsclassname="filter">

<html xmlns="http://www.w3.org/1999/xhtml">
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
		<title>Untitled Document</title>

		<!-- JQUERY LIBRARY -->
		<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js" type="text/javascript"></script>

		<!-- JQUERY_RESULT_FILTER.JS -->
		<script src="js/jquery_result_filter.js" type="text/javascript"></script>
	</head>

	<body>
		Filter:
		<input type="text" name="filter" id="filter" value="" /><br /><br /><br />

		<p>Data:</p>
		<div id="output"></div>
	</body>
</html>

We have here a a proxy at the top that allows us to make asynchronous AJAX calls to the Coldfusion server. For javascript we load in the jQuery library and our javascript file that handles the AJAX calls and the data output to the DOM. In the body there is an input field which serves as our filter and an empty div which will have data loaded into it dynamically using jQuery.

Let’s take a look at our component to see how the data is being processed as the user types their filter.

(more…)

Create query dynamically / Get query data dynamically

Sunday, February 7th, 2010

It’s hard to sum this subject up in a title so let me explain a little more.  Let’s say you have two tables in a database.  One is named ‘product_prices_tbl’ and the other is called ‘product_quantities_tbl’.  In both tables you have a key called product_id that represents the individual products associated with each price and quantity.  So what we want is to get the price and quantity of the product that has an id of ’4′, but we only want to write one query that will run twice – first for the prices table and second for the quantities table.  First let’s build some queries.

I’ve created a CFC to do the work for me.  It has one main public function called ‘getData’ and two private methods called by the getData() method called ‘getPrices’ and ‘getQuantities’.  The two private methods simply create their respective query and return it to the getData() method to be worked with.  So just for reference I’ll post the two private methods and what they return.

getPrices() Private Method

<!--- ********************************  CREATE PRICES QUERY  ******************************** --->
<cffunction name="getPrices" displayname="Get Prices" description="Creates a query of product prices." access="private" output="false" returntype="query">

	<!--- CREATE A QUERY --->
	<cfset var product_price_tbl = querynew("product_id, product_price")>

	<!--- LOOP TO SET DATA INTO QUERY --->
	<cfloop from="1" to="10" index="i">
		<!--- CREATE A NEW ROW TO BOTH TABLES --->
		<cfset queryaddrow(product_price_tbl, 1)>

		<!--- SELECT A NUMBER BETWEEN 1 AND 100 TO BE PRICE --->
		<cfset myprice = randrange(1, 100)>

		<!--- SET OUR ID EQUAL TO THE INDEX AND THE PRICE EQUAL TO OUR NUMBER BETWEEN 1 AND 100 --->
		<cfset querysetcell(product_price_tbl, "product_id", i)>
		<cfset querysetcell(product_price_tbl, "product_price", decimalformat(myprice))>
	</cfloop>

	<!--- RETURN QUANTITIES QUERY --->
	<cfreturn product_price_tbl>

</cffunction>

getQuantities() Private Method

<!--- ********************************  CREATE QUANTITIES QUERY  ******************************** --->
<cffunction name="getQuantities" displayname="Get Quantities" description="Creates a query of product quantities." access="private" output="false" returntype="query">

	<!--- CREATE A QUERY --->
	<cfset var product_quantity_tbl = querynew("product_id, product_quantity")>

	<!--- LOOP TO SET DATA INTO QUERY --->
	<cfloop from="1" to="10" index="i">
		<!--- CREATE A NEW ROW TO BOTH TABLES --->
		<cfset queryaddrow(product_quantity_tbl, 1)>

		<!--- SELECT A NUMBER BETWEEN 1 AND 5 TO BE QUANTITY --->
		<cfset myquantity = randrange(1, 5)>

		<!--- SET OUR ID EQUAL TO THE INDEX AND THE QUANTITY EQUAL TO OUR NUMBER BETWEEN 1 AND 5 --->
		<cfset querysetcell(product_quantity_tbl, "product_id", i)>
		<cfset querysetcell(product_quantity_tbl, "product_quantity", myquantity)>
	</cfloop>

	<!--- RETURN QUANTITIES QUERY --->
	<cfreturn product_quantity_tbl>

</cffunction>

(more…)

Accessing a query resultset by row number

Tuesday, January 12th, 2010

I ran into a little issue this morning of needing to access a query resultset not by column or item id or anything usual.  Instead I needed to access data in the query via the row number.  This is not something that occurs often for me.  In fact this is the first time I’ve encountered this.

I checked Adobe’s docs and found no method immediately accessible for getting a row of my choice.  The closest I found was the currentRow() method that can be used when looping through a query.

Knowing Java has a slew of methods for working with query result sets I turned to the java docs.  Sure enough I found a way to use java methods to return specific data about a row of my choice.  Afterwards, I found on Ben Nadel’s blog a post about converting a query into an array.  He posts there a way of accessing the query object as a struct.  So let’s take a look at a quick example of how to use both.

First let’s create a query to work with.

Create Query

<!--- CREATE LIST --->
<cfset VARIABLES.listofcolors = "blue, red, purple, green, yellow, magenta">

<!--- CREATE A COUNTER --->
<cfset VARIABLES.counter = 22>

<!--- CREATE QUERY --->
<cfset VARIABLES.getQuery = querynew("id, colors")>

<!--- LOOP OVER COLORS --->
<cfloop list="#VARIABLES.listofcolors#" index="VARIABLES.i">
	<!--- CREATE A NEW ROW IN QUERY --->
	<cfset queryaddrow(VARIABLES.getQuery, 1)>

	<!--- ADD DATA --->
	<cfset querysetcell(VARIABLES.getQuery, "id", VARIABLES.counter)>
	<cfset querysetcell(VARIABLES.getQuery, "colors", VARIABLES.i)>

	<!--- INCREASE COUNTER BY 1 --->
	<cfset VARIABLES.counter = VARIABLES.counter + 1>
</cfloop>

(more…)

Recording decimal numbers into a MySQL database

Friday, November 20th, 2009

I had a little problem this afternoon that took me a few minutes to figure out. I was trying to insert a price into a MySQL database using the Coldfusion <cfquery> tag. This was my problem. I set up the database to accept decimals. So I have a column data-typed to DECIMAL(5,2). So I can store a 5 digit number that always has two decimal places. All is fine with this. If I hard code a price such as 14.98 into an INSERT statement there is no problem. But when I insert it dynamically using Coldfusion I get 14.00 inserted into the database. Let’s take a look at what I was trying to do.

<cfset VARIABLES.price = 14.98>
<cfquery name=”insertPrice” datasource=”datasource”>
INSERT INTO mytable_tbl (price)
VALUES (<cfqueryparam value=”#VARIABLES.price#” cfsqltype=”cf_sql_decimal”>)
</cfquery>

So I have a price of 14.98 set into a variable called ‘price’.  All I want to do is insert this price into a column called price (data-typed DECIMAL(5,2)) into mytable_tbl table using a query statement.  However, running this statement enters ’14.00′ into the database.  After trying some things I realized that there are a few more attributes in the <cfqueryparam> tag that I just didn’t know about.  I use <cfqueryparam> religiously, but have never really had reason to take it beyond the ‘value’ and a cfsqltype of ‘varchar’ or ‘numeric’ before.  But as it turns out when using ‘cf_sql_decimal’ as the cfsqltype you can also, and should, use another attribute called ‘scale’. So our new SQL statement looks like the following.

<cfquery name=”insertPrice” datasource=”datasource”>
INSERT INTO mytable_tbl (price)
VALUES (<cfqueryparam value=”#VARIABLES.price#” cfsqltype=”cf_sql_decimal” scale=”2″>)
</cfquery>

Simple solution.  One I just didn’t know about.  I’ll also note that I have since checked the docs and sure enough it’s there. Just a reminder to always check the docs first.