Wrox Programmer Forums
Go Back   Wrox Programmer Forums > Database > SQL Language
|
SQL Language SQL Language discussions not specific to a particular RDBMS program or vendor.
Welcome to the p2p.wrox.com Forums.

You are currently viewing the SQL Language section of the Wrox Programmer to Programmer discussions. This is a community of software programmers and website developers including Wrox book authors and readers. New member registration was closed in 2019. New posts were shut off and the site was archived into this static format as of October 1, 2020. If you require technical support for a Wrox book please contact http://hub.wiley.com
 
Old March 14th, 2004, 09:58 PM
Registered User
 
Join Date: Mar 2004
Posts: 6
Thanks: 0
Thanked 0 Times in 0 Posts
Default MS Access Query using sql/asp

    I'm looking for a way to retrieve records from an Access db to be displayed in a table.

I will be getting a string or numeric value from the user and converting it input to a single type.

Then I want to search a field called "value" in my db to see if the user input value is between the values in my field.

Then I want to output ONLY those rows/records that meet the filtering criteria.

The field is titled "value" and it contains strings like the following: "10-50k"

I've already written a function that can convert the string data from the value field and the user input into three separate numbers to do the comparison.

THE PROBLEM:

I don't know whether to filter the records before or after creating the recordset.

When I perform the comparison after calling the entire db out, it is easy to make the comparison, but not so easy to accurately monitor the paging.

On the other hand, I don't know how to build the SQL to do a complex conversion/comparison "on the fly", so as to only include filtered records.


ex. user input: =
    4.7k


ex. table=
    id name value size
    1 elf 10-50k 10
    2 joker 50k-100g 50
    3 oscar 50k-200m 14


desired output=
    id name value size
    1 elf 10-50k 10


Thanks,
ja



ja
 
Old March 15th, 2004, 04:31 AM
joefawcett's Avatar
Wrox Author
 
Join Date: Jun 2003
Posts: 3,074
Thanks: 1
Thanked 38 Times in 37 Posts
Default

Well it would be better before from a performance point of view but your filter expression is going to be awkward because your table is non-normalised, the 'value' column has three pieces of data, minimum, maximum and unit type, it would be a lot easier if these were spread over three fields. As you are using Access you will probably need to write a module based function which accepts a field's data and the user input and tests whether it matches. Then if your function were called 'isInRange' your SQL would look like:
Code:
SELECT [id], [name], [value], [size]
FROM tblData
WHERE isInRange([value], <user input>) = TRUE
--

Joe
 
Old March 15th, 2004, 10:04 AM
Registered User
 
Join Date: Mar 2004
Posts: 6
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Thanks Joe,
I guess normalizing the data should be goal number one. I realized this early on but decided to "tough-it-out" and try to come up with a clever solution.

Per your suggestion, I'll try using my function in the where clause.



ja
 
Old March 15th, 2004, 11:46 AM
Registered User
 
Join Date: Mar 2004
Posts: 6
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Well joe,
It seems so logical to build the sql string as you suggested.

However, now I get "undefined Function" error.

I renamed the field to "range" to eliminate reserved word conflict.

The function captures user input so I don't think i need to include it as a func. param.



ja
 
Old March 15th, 2004, 12:02 PM
joefawcett's Avatar
Wrox Author
 
Join Date: Jun 2003
Posts: 3,074
Thanks: 1
Thanked 38 Times in 37 Posts
Default

What code do you have for your isInRange function?

--

Joe
 
Old March 15th, 2004, 12:27 PM
Registered User
 
Join Date: Mar 2004
Posts: 6
Thanks: 0
Thanked 0 Times in 0 Posts
Default

The code for the function merely reduces the "3" strings to thier numeric form.

It works fine when I use it "after" calling out the entire db using: "If isInRange(fldF.Value) = true Then...display the record"

The problem there is that the other fields in the record get displayed before the function is called. So, if isInRange returns false I have part of a record that I don't wish to see.



ja
 
Old March 15th, 2004, 12:35 PM
Registered User
 
Join Date: Mar 2004
Posts: 6
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Here's the function code:

Function ConvertDbCellValue (varRaw)
'response.Write varRaw
'response.End()
'/////This sub-routine converts the database value field into two numbers
'/////which represent the low end and high end of the value range
Dim iStart, iStrLen, iDashLoc, strUserInput, strRangeLow, strRangeHigh, sngRangeLow, sngRangeHigh, sngUserInput, varUserValMult, varCellValMult
'/////Initialize some variables
    iStart = 1
    iStrLen = Len(varRaw)
'/////Find the hyphen
    iDashLoc = instr(iStart, varRaw, "-")
'/////Return the string before the hyphen
    strRangeLow = Mid(varRaw, iStart, (iDashLoc-1))
'/////Test to see if the last character is numeric
'/////If NOT then find out what it is and multiply the numeric portion
'/////of the string by the appropriate multiplier
    If NOT IsNumeric(right(strRangeLow,1)) Then
            Select Case UCase(right(strRangeLow,1))
            Case "K"
                sngRangeLow = CSng(Mid(strRangeLow, 1, Len(strRangeLow) - 1))
                sngRangeLow = sngRangeLow * 1000
            Case "M"
                sngRangeLow = CSng(Mid(strRangeLow, 1, Len(strRangeLow) - 1))
                sngRangeLow = sngRangeLow * 1000000
            Case "G"
                sngRangeLow = CSng(Mid(strRangeLow, 1, Len(strRangeLow) - 1))
                sngRangeLow = sngRangeLow * 1000000000
            Case "T"
                sngRangeLow = CSng(Mid(strRangeLow, 1, Len(strRangeLow) - 1))
                sngRangeLow = sngRangeLow * 1000000000000
            Case Else
                Response.Write("Contact the <a href='MAILTO:'>webmaster</a>")
        End Select
    Else
'/////If the last character IS numeric then convert the string to SINGLE and set it = to the variable
        sngRangeLow = CSng(strRangeLow)
    End If
'/////SEE NOTES ABOVE
    strRangeHigh = Mid(varRaw, (iDashLoc + 1), (iStrLen - iDashLoc))
        If NOT IsNumeric(right(strRangeHigh,1)) Then
            Select Case UCase(right(strRangeHigh, 1))
            Case "K"
                sngRangeHigh = CSng(Mid(strRangeHigh, 1, Len(strRangeHigh) - 1))
                sngRangeHigh = sngRangeHigh * 1000
            Case "M"
                sngRangeHigh = CSng(Mid(strRangeHigh, 1, Len(strRangeHigh) - 1))
                sngRangeHigh = sngRangeHigh * 1000000
            Case "G"
                sngRangeHigh = CSng(Mid(strRangeHigh, 1, Len(strRangeHigh) - 1))
                sngRangeHigh = sngRangeHigh * 1000000000
            Case "T"
                sngRangeHigh = CSng(Mid(strRangeHigh, 1, Len(strRangeHigh) - 1))
                sngRangeHigh = sngRangeHigh * 1000000000000
            Case Else
                Response.Write("Contact the <a href='mailto:'>webmaster</a>")
        End Select
    Else
        sngRangeHigh = CSng(strRangeHigh)
    End If
'/////////////////////////Convert User Input///////////////////////////////////

    strUserInput = Trim(varUserInputValue)
    If NOT IsNumeric(right(strUserInput,1)) Then
            Select Case UCase(right(strUserInput,1))
            Case "K"
                sngUserInput = CSng(Mid(strUserInput, 1, Len(strUserInput) - 1))
                sngUserInput = sngUserInput * 1000
            Case "M"
                sngUserInput = CSng(Mid(strUserInput, 1, Len(strUserInput) - 1))
                sngUserInput = sngUserInput * 1000000
            Case "G"
                sngUserInput = CSng(Mid(strUserInput, 1, Len(strUserInput) - 1))
                sngUserInput = sngUserInput * 1000000000
            Case "T"
                sngUserInput = CSng(Mid(strUserInput, 1, Len(strUserInput) - 1))
                sngUserInput = sngUserInput * 1000000000000
            Case Else
                Response.Write("Contact the <a href='MAILTO:'>webmaster</a>")
        End Select
    Else
        sngUserInput = CSng(strUserInput)
    End If
    If sngUserInput >= sngRangeLow and sngUserInput <= sngRangeHigh then
        ConvertDbCellValue = true
    Else
        ConvertDbCellValue = false
    End If
strRangeLow = ""
strRangeHigh = ""
strUserInput = ""
sngRangeLow = ""
sngRangeHigh = ""
sngUserInput = ""
End Function


ja
 
Old March 16th, 2004, 05:15 PM
Registered User
 
Join Date: Mar 2004
Posts: 6
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Joe thanks for the advice. I ended up just normalizing the data in the database.
After that it was a piece of cake to compare fields.

I just used CDbl([cell_name]) <= varUserInputValue.

It works like a charm.

Beers on me.

ja
 
Old March 17th, 2004, 05:15 AM
joefawcett's Avatar
Wrox Author
 
Join Date: Jun 2003
Posts: 3,074
Thanks: 1
Thanked 38 Times in 37 Posts
Default

Quote:
quote:Originally posted by redhorse
Beers on me.
Well I'm in the States in April, unfortunately I'll be in Seattle which is a little far from Rhode Island.



--

Joe





Similar Threads
Thread Thread Starter Forum Replies Last Post
MS Access Query neha2007 SQL Language 1 July 12th, 2007 10:11 AM
Database migration MS Access 2003 to MS SQL 2000 ayazhoda SQL Server 2000 3 April 23rd, 2007 11:38 AM
MS ACCESS 2003 FRONTEND AND MS SQL SERVER 2005 DB mohankumar0709 SQL Server 2005 3 March 23rd, 2007 12:48 AM
I am trying to convert a MS Access Query to a SQL? WebLadyBug SQL Server ASP 3 March 9th, 2007 12:39 PM
Problem with SQL (MS-Access) and ASP DaPrince Access ASP 4 August 14th, 2004 08:11 AM





Powered by vBulletin®
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
Copyright (c) 2020 John Wiley & Sons, Inc.