Please start any new threads on our new site at https://forums.sqlteam.com. We've got lots of great SQL Server experts to answer whatever question you can come up with.

 All Forums
 SQL Server 2000 Forums
 SQL Server Development (2000)
 Executing Custom Biz Logic in Package?

Author  Topic 

jesus4u
Posting Yak Master

204 Posts

Posted - 2003-01-24 : 13:57:02
I now have need of knowing if I can write my own business logic within a package? I see there is the ability to use VBScript which is cool but is that the way?

Thanks in advance

robvolk
Most Valuable Yak

15732 Posts

Posted - 2003-01-24 : 14:09:40
It depends on what the logic has to do. If it's fairly simple code-wise and it can be written in VBScript then it's probably best to put it into an ActiveX step. But if it's more complex, and/or it's already encapsulated in a COM object, then simply call that COM object from an ActiveX step.

And if all of the business logic revolves around manipulating data WITHIN the database, then put the logic into a stored procedure. The closer you can keep the logic to the data/database, the better. The only time you should really have to go outside the database is for a service or function that T-SQL cannot do (like getting credit card authorizations, sending email, advanced math or financial functions, or screen-scraping a web page)

If you can give more detail on what exactly you need to do, we can better advise on how to do it.

Go to Top of Page

jesus4u
Posting Yak Master

204 Posts

Posted - 2003-01-24 : 14:15:18
Thank you. Well in terms of biz logic I am having to create our own custom webstats based upon that logfile table you helped me with in the other thread. Those records will be analyzed by the code and then the results will be entered into about 4 other tables. I was thinking of using cursors in a SP to do all this.

Follow me?

Go to Top of Page

robvolk
Most Valuable Yak

15732 Posts

Posted - 2003-01-24 : 14:36:45
eeeeeeeeeeeeeewwwwwwwwwwwwwwwww, cursors

DON'T DO IT!

Naturally, if you post some more detail about what the analysis has to go, I'll bet someone will find a non-cursor approach.

Go to Top of Page

jesus4u
Posting Yak Master

204 Posts

Posted - 2003-01-24 : 14:38:49
well then here is the prototype code written in VBScript. This is what I need to do. Naturally alot of this logic I don't need to do because of the package parsing into the tables etc..


err.Clear

' Get Track ID
strTrackID = trim(Request.QueryString("tid"))

' Grab The Referrer
strReferrer = Request.ServerVariables("HTTP_REFERER")
strTempRef = CleanDomain(strReferrer)

' This is where the requestor is wanting to go
strDestinationUrl = Request.ServerVariables("SERVER_NAME") & Request.ServerVariables("URL")
strTempDestin = CleanDomain(strDestinationUrl)

' this means that the TrackID has NOT been logged for this session and
' should be logged in the database.
'if NOT lcase(Request.Cookies("777_777")) = lcase(trim(strTrackID)) then

' If the urls are not the same then run the code
if NOT (lcase(strTempef) = lcase(strTempDestin)) OR len(strTrackID) > 0 then

' First: Check For Valid TrackID
' TrackID can be right, wrong or empty
if NOT TrackIDIsValid(strTrackID, strRedirectUrl) then
'strRedirectUrl = wt.TrackIDIsValid(strTrackID, strReferrer)
'set wt = nothing
'if len(strRedirectUrl) = 0 then
' Grab the root url from the referrer
if len(strReferrer) > 0 then
strDomainName = GetRootURL(strTempRef)
else
' there was no referrer so it is anonymous
strDomainName = "Anonymous"
end if

'#1 lookup domain name/referrer in the users table ex. Google.com
if len(strDomainName) > 0 then
intCurrentUserID = EnterDomainName(strDomainName, strReferrer)
end if

' We have a CurrentUserID now.

'#2 Look up the Destination url in TheDestinations table first; Return the ID
if instr(1, strDestinationUrl, strNameOfTrackingPage) = 0 then
' returns the id of: ex. CoralRidgeHour = 2
intDestinationID = GetDestinationUrlId(strDestinationUrl)
end if

' We have a DestinationID now.

'#3 Check if the intCurrentUserID and intDestinationID EXIST in
' TheUserDetails table. If so, then use the TRACKID.
strTrackID = CheckForTrackID(intCurrentUserID, intDestinationID)

' no TrackID found so create one.
if len(strTrackID) = 0 then
strTrackID = GetNewGUID
call EnterNewTrackIDForDestinationID(strTrackID, intCurrentUserID, intDestinationID)
end if

call LogHit(strTrackID, strReferrer, intCurrentUserID, intDestinationID)

' Away we go!
Set conn = nothing
' Set cookie so that when other pages that are including this code, the hit
' won't be re-logged.
Response.Cookies("777_777") = strTrackID
else
Set conn = nothing
Response.Cookies("777_777") = strTrackID
Response.Redirect strRedirectUrl
end if


end if



'end if







Edited by - jesus4u on 01/24/2003 14:39:50
Go to Top of Page

robvolk
Most Valuable Yak

15732 Posts

Posted - 2003-01-24 : 15:43:05
Hmmmm...unfortunately the code doesn't help me see the process. There are user-defined functions in there too that weren't included in the code.

It would be better to just describe what you're trying to do with the code. If you want to put data in a table, show the table structure. If you're updating, describe the process. If there's analysis, what columns/values in what tables are affected or necessary, etc. The structure of the tables used in this process are very important, please post the full DDL for them, and if you can provide a sample of the input and how it should look after processing, that would help a great deal. Just a few rows that show all the possible effects of the analysis would be fine.

Go to Top of Page

jesus4u
Posting Yak Master

204 Posts

Posted - 2003-01-24 : 16:06:38
would it be faster to do if then logic in the ActiveX scripting in a package than with a cursor in a sp???

Go to Top of Page

robvolk
Most Valuable Yak

15732 Posts

Posted - 2003-01-24 : 17:04:07
The fastest methods, in order, would be:

1. Set-based INSERT & UPDATE statements that affect the tables;
2. SQL Server procedures using cursors;
3. ActiveX script

If your current VB code is accessing the database via the user-defined functions, this will add a great deal of unnecessary overhead. Cursors in a sproc would be faster, but doing everything as set-based ops would be faster still. Again, if this is only affecting data, there's really no need for ActiveX at all. And there's no need to use cursors to move from one ID/URL/Log record to the next, testing each one individually, when you can test the entire set in one shot.

Go to Top of Page

jesus4u
Posting Yak Master

204 Posts

Posted - 2003-01-27 : 08:13:49
quote:

The fastest methods, in order, would be:

1. Set-based INSERT & UPDATE statements that affect the tables;
2. SQL Server procedures using cursors;
3. ActiveX script

If your current VB code is accessing the database via the user-defined functions, this will add a great deal of unnecessary overhead. Cursors in a sproc would be faster, but doing everything as set-based ops would be faster still. Again, if this is only affecting data, there's really no need for ActiveX at all. And there's no need to use cursors to move from one ID/URL/Log record to the next, testing each one individually, when you can test the entire set in one shot.





Sorry for my ignorance but what do you mean by "Set-based INSERT & UPDATE statements that affect the tables"?

Thanks

Go to Top of Page

robvolk
Most Valuable Yak

15732 Posts

Posted - 2003-01-27 : 08:16:50
Just regular INSERT or UPDATE statements that do not use a cursor. If you had a process that needed to move through one table, get a value from it, then compare it to another table, you might use a cursor for that but it would be much faster to do it using a JOIN, for example. I can't tell exactly what the process you have now does exactly, but I have a feeling that it can all be reduced to data in a table or tables, and the data processing can be done using regular SQL commands; no cursors, no loops.

Go to Top of Page

jesus4u
Posting Yak Master

204 Posts

Posted - 2003-01-27 : 08:26:07
More specifically this is what needs to be done after I import an IIS 5.0 logfile into the WebLog table. For this conversation imagine all the Client Ip's being different for a given day. I need to append a "?tid=somenumber" to the end of only the first url requested for an IP in a day. The rest are to be ignored. That is a basic anaylsis that needs to be done.

WebLog table:


Sample Data:


Sample Output:
/hr/login.asp?tid=somenumber

Go to Top of Page

jesus4u
Posting Yak Master

204 Posts

Posted - 2003-01-27 : 15:35:50
anyone, help please???

Go to Top of Page

robvolk
Most Valuable Yak

15732 Posts

Posted - 2003-01-27 : 15:40:12
UPDATE W
SET PageRequested=PageRequested + '?tid=somenumber'
FROM WebLog W INNER JOIN
(SELECT IP, Min(ID) AS MinID FROM WebLog
WHERE [Date]='01/23/2002'
GROUP BY IP) Y
ON W.ID=Y.MinID


Once the web log has been imported and parsed into the table, you'd run that UPDATE statement. You'd have to change the date in the WHERE clause though, if you'd like it to run without needing to do so:

UPDATE W
SET PageRequested=PageRequested + '?tid=somenumber'
FROM WebLog W INNER JOIN
(SELECT IP, Min(ID) AS MinID FROM WebLog
WHERE [Date]=(SELECT Max([Date]) FROM WebLog)
GROUP BY IP) Y
ON W.ID=Y.MinID


However, you'd have to run that each time you load a new day's logs, you can't load an entire week's worth of logs and do it, it would only update the latest day's rows.

<edit> fixed a !#$%#$ typo I missed earlier </edit>

Edited by - robvolk on 01/27/2003 15:46:33
Go to Top of Page

jesus4u
Posting Yak Master

204 Posts

Posted - 2003-01-27 : 15:50:06

Attempting to use your code I get

Invalid column name 'ID'.


Go to Top of Page

robvolk
Most Valuable Yak

15732 Posts

Posted - 2003-01-27 : 15:55:03
Great, the joys of a case-sensitive server:

UPDATE W
SET PageRequested=PageRequested + '?tid=somenumber'
FROM WebLog W INNER JOIN
(SELECT IP, Min(id) AS MinID FROM WebLog
WHERE [Date]=(SELECT Max([Date]) FROM WebLog)
GROUP BY IP) Y
ON W.id=Y.MinID


If your server is case-insensitive, make sure you use the modified version of the code; the original post had an incorrect JOIN clause.

Go to Top of Page

jesus4u
Posting Yak Master

204 Posts

Posted - 2003-01-27 : 16:05:43
this is very good but why does one have to use the join?
thanks

Go to Top of Page

robvolk
Most Valuable Yak

15732 Posts

Posted - 2003-01-27 : 16:12:25
For each IP address, it finds the minimum ID number for that day's data...which translates to the "first" or "earliest" requested page. By JOINing this back to the WebLog table on the ID column, the UPDATE statement will change ONLY those ID's, representing the rows you want to modify. This is far more efficient than using a cursor to navigate the table and perform updates on a row-by-row basis.

Go to Top of Page

jesus4u
Posting Yak Master

204 Posts

Posted - 2003-01-27 : 16:14:20
quote:

For each IP address, it finds the minimum ID number for that day's data...which translates to the "first" or "earliest" requested page. By JOINing this back to the WebLog table on the ID column, the UPDATE statement will change ONLY those ID's, representing the rows you want to modify. This is far more efficient than using a cursor to navigate the table and perform updates on a row-by-row basis.





MAN oh MAN is that efficient! I am mainly a software developer dabbling in sql everyday now and a whole nother world is emerging on the horizon for me.

Go to Top of Page

jesus4u
Posting Yak Master

204 Posts

Posted - 2003-01-27 : 16:34:22
Sorry to keep bothering you but how do I make a condition of several strings that I don't want to find in the records?
Like '.gif','.jpg' etc..?

This is the statement so far


UPDATE as W
SET PageRequested=PageRequested + '?tid=somenumber'
FROM WebLog as W INNER JOIN
(SELECT IP, Min(ID) AS MinID FROM WebLog
WHERE [Date]=(SELECT max([Date]) FROM WebLog) and CHARINDEX('tid=', PageRequested) = 0
GROUP BY IP) as Y
ON W.ID=Y.MinID



Go to Top of Page

robvolk
Most Valuable Yak

15732 Posts

Posted - 2003-01-27 : 18:17:43
Something like:

UPDATE as W
SET PageRequested=PageRequested + '?tid=somenumber'
FROM WebLog as W INNER JOIN
(SELECT IP, Min(ID) AS MinID FROM WebLog
WHERE [Date]=(SELECT max([Date]) FROM WebLog) AND CHARINDEX('tid=', PageRequested) = 0
AND PageRequested NOT LIKE '%.jpg%' AND PageRequested NOT LIKE '%.gif%'
GROUP BY IP) as Y
ON W.ID=Y.MinID


If you have a lot of file extensions you want excluded (more than 25) or they change on a frequent basis, you can set up an exclusionary table and JOIN it using a LIKE or NOT LIKE condition. Although if you don't want those files included in this process, why not just DELETE their rows?

Go to Top of Page

jesus4u
Posting Yak Master

204 Posts

Posted - 2003-01-28 : 07:49:26
quote:

Although if you don't want those files included in this process, why not just DELETE their rows?



That is a good point.

Go to Top of Page
    Next Page

- Advertisement -