PHP Wizards

From: Peter (BOUGHTONP)20 Apr 2011 22:37
To: Ken (SHIELDSIT) 80 of 101
Did you ORDER BY counted_column DESC or something more complicated?
From: Ken (SHIELDSIT)20 Apr 2011 22:48
To: Peter (BOUGHTONP) 81 of 101

I'll show you after I eat supper. I can't remember really.

 

But I rebuilt the whole code and cleaned it all up. It required much less math and variables. So I thank you for that! Plus I formatted it as you suggested and that helps a lot.

From: Ken (SHIELDSIT)20 Apr 2011 23:26
To: Peter (BOUGHTONP) 82 of 101
This is what I did. It let me eliminate a bunch of if's and other math.
code:
<CFQUERY NAME="sluth" DATASOURCE="isiswood">
	SELECT ID=rudID, Category=rudCategory, Seq=rudSeq, Type=rudType, Product_ID=rudProductID, Description=rudDescrip, 
	PcsPerPkg=rudPcsPerPkg, Tally=rudTally, UOM=rudBaseUnitID, Pieces=rudPieces, Volume=rudVolume, NetVolume=rudNetVolume, Cost=rudCost, AddedCost= rudAddedCost, MktValue=rudMarketValue, Total=rudTotal, NetThick=rudNetThick, 
	NetWidth=rudNetWidth, NetLength=rudNetLength, NetType=rudVolType, LocationID=rudLocationID,rudFIFOVolume,rudForceCost,rudBoomID,prdLengthID=(SELECT prdLengthID 
	FROM ProductMaster WHERE prdID=rudProductID) FROM ProductionDetail WHERE rudID='#form.batch#' AND rudCategory='Produced' AND rudProductID LIKE '%#WoodType#%' AND rudDescrip NOT LIKE '%boards%' AND rudDescrip NOT LIKE '%blocking%'
	ORDER BY Seq;
</cfquery>
From: Ken (SHIELDSIT)20 Apr 2011 23:39
To: Peter (BOUGHTONP) 83 of 101
Here is my code after your help.
Attachments:
From: Peter (BOUGHTONP)21 Apr 2011 00:23
To: Ken (SHIELDSIT) 84 of 101
Much better... though still a whole bunch of stuff I want to change there. :$

But anyway, yeah, if you make it to "ORDER BY WoodCount DESC" in your count query, then all you need is <cfset WoodType = Count.WoodType[1] /> instead of that cfoutput loop.

(Or, you can skip that entirely, and later on just use #Count.WoodType[1]# directly.)

You can probably save a small bit of memory by putting a "TOP 1" after the SELECT too, since by then you'll only care about the first row, but it'll still work without that, just not as efficiently.


All this is just an internal tool, yes - not something that will be publicly available?

In general, you should never directly do #form.whatever# or #url.whatever# or #cookie.whatever# inside a cfquery, because it potentially allows people to inject SQL, which is bad.

Solution is to use query parameters, like this:
code:
AND rudID = <cfqueryparam value="#form.batch#" />


Which prevents SQL injection (and sometimes makes it easier for a database to optimise queries, so can make it faster too).

Same thing applies on the HTML side - to prevent people injecting HTML/JavaScript you need to use HtmlEditFormat for any unsanitized user input:
code:
Run ID = <cfoutput>#HtmlEditFormat(form.batch)#</cfoutput>


Of course, that matters more for stuff on the actual internet - if this is a local tool then it's a question of if you can trust your work colleagues, but both of them are good habits to get into. :)
EDITED: 21 Apr 2011 00:24 by BOUGHTONP
From: Ken (SHIELDSIT)21 Apr 2011 00:53
To: Peter (BOUGHTONP) 85 of 101

Yes just an internal tool so I'm not really concerned about injections, but you're right. Get in the habit!

 

I have no doubt there are things that need changed. I haven't used CF in about 2 years and even then I wasn't what I would consider much good at it.

From: Ken (SHIELDSIT)21 Apr 2011 13:17
To: Peter (BOUGHTONP) 86 of 101
Any idea why this would work:

code:
WHERE rudID='#form.batch#' AND rudCategory='Produced' AND rudProductID LIKE '%#WoodType#%' AND rudDescrip NOT LIKE '%boards%' AND rudDescrip NOT LIKE '%blocking%'


And this wouldn't?

code:
WHERE rudID='#form.batch#' AND rudCategory='Produced' AND rudProductID LIKE '%#WoodType#%' AND rudDescrip LIKE '%boards%' AND rudDescrip LIKE '%blocking%'


It tells me this:

quote:
Can't cast Complex Object Type Query to String
EDITED: 21 Apr 2011 13:19 by SHIELDSIT
From: Peter (BOUGHTONP)21 Apr 2011 13:42
To: Ken (SHIELDSIT) 87 of 101
It's not the NOTs that are making it not work (and if it was, they would give an SQL error instead).

The error message says you're trying to use a Query variable as if it were a String, and a query can't be implicitly converted (like numbers,booleans,etc can), so it falls over and complains.

Did you do the change in msg:38393.84 and/or anything else?

You've only got two variables shown, form.batch and WoodType - and neither of them should be queries based on the previous code, so either the code has changed, or the data has changed and is causing different behaviour in the code.

Is that definitely the line that the error is pointing to?
If so, are there any other variables inside the cfquery block?
From: Ken (SHIELDSIT)21 Apr 2011 13:47
To: Peter (BOUGHTONP) 88 of 101
No the only thing I changed was removing the NOT.

This works:
code:
<CFQUERY NAME="woodtype" DATASOURCE="isiswood">
	SELECT ID=rudID, Category=rudCategory, Seq=rudSeq, Type=rudType, Product_ID=rudProductID, Description=rudDescrip, 
	PcsPerPkg=rudPcsPerPkg, Tally=rudTally, UOM=rudBaseUnitID, Pieces=rudPieces, Volume=rudVolume, NetVolume=rudNetVolume, Cost=rudCost, AddedCost= rudAddedCost, MktValue=rudMarketValue, Total=rudTotal, NetThick=rudNetThick, 
	NetWidth=rudNetWidth, NetLength=rudNetLength, NetType=rudVolType, LocationID=rudLocationID,rudFIFOVolume,rudForceCost,rudBoomID,prdLengthID=(SELECT prdLengthID 
	FROM ProductMaster WHERE prdID=rudProductID) FROM ProductionDetail WHERE rudID='#form.batch#' AND rudCategory='Produced' AND rudProductID LIKE '%#WoodType#%' AND rudDescrip NOT LIKE '%boards%' AND rudDescrip NOT LIKE '%blocking%'
	ORDER BY Seq;
</cfquery>


This doesn't:
code:
<CFQUERY NAME="bandb" DATASOURCE="isiswood">
	SELECT ID=rudID, Category=rudCategory, Seq=rudSeq, Type=rudType, Product_ID=rudProductID, Description=rudDescrip, 
	PcsPerPkg=rudPcsPerPkg, Tally=rudTally, UOM=rudBaseUnitID, Pieces=rudPieces, Volume=rudVolume, NetVolume=rudNetVolume, Cost=rudCost, AddedCost= rudAddedCost, MktValue=rudMarketValue, Total=rudTotal, NetThick=rudNetThick, 
	NetWidth=rudNetWidth, NetLength=rudNetLength, NetType=rudVolType, LocationID=rudLocationID,rudFIFOVolume,rudForceCost,rudBoomID,prdLengthID=(SELECT prdLengthID 
	FROM ProductMaster WHERE prdID=rudProductID) FROM ProductionDetail WHERE rudID='#form.batch#' AND rudCategory='Produced' AND rudProductID LIKE '%#WoodType#%' AND rudDescrip LIKE '%boards%' OR rudDescrip LIKE '%blocking%'
	ORDER BY Seq;
</cfquery>
From: Peter (BOUGHTONP)21 Apr 2011 13:53
To: Ken (SHIELDSIT) 89 of 101

And the name of the query. :P

 

Do you happen to have both queries in the code, but the second query is after the first one?

 

Cus if so, once the first query has executed, the WoodType variable will be replaced with that query, and so the second one will fall over when it tries to use the original WoodType string.

 

(Which is exactly what the error is suggesting.)

 

A simple way to avoid it is to prefix or suffix all query variables, (so you could call it qryWoodType or WoodTypeQry and it wouldn't conflict with the original WoodType string), or you can give it a completely different name.

EDITED: 21 Apr 2011 13:54 by BOUGHTONP
From: Ken (SHIELDSIT)21 Apr 2011 13:57
To: Peter (BOUGHTONP) 90 of 101
I'm a dumbass. Thanks, that was it!
From: Ken (SHIELDSIT)23 Apr 2011 20:36
To: Peter (BOUGHTONP) 91 of 101
Pete you any good with the dates in CF? I need to search by month and year. I'm pretty sure I can use #LEFT and #MID. Is that how you would approach it?
From: Peter (BOUGHTONP)23 Apr 2011 21:11
To: Ken (SHIELDSIT) 92 of 101
Treat dates as dates, not strings. Convert to dates as soon as possible ( parseDate or parseDateTime ) and don't convert back to string until you have to.

If you're doing database date stuff, look up the native stuff ( DatePart or DateTrunc or whatever ), and use cfqueryparam with either cf_sql_date or cf_sql_timestamp (for dates/datetimes as appropriate).

Unless you've got *just* doing month and year stuff, in which case it's integers and Year and Month functions.
From: Ken (SHIELDSIT)25 Apr 2011 15:44
To: Peter (BOUGHTONP) 93 of 101
Do you have a few minutes today to assist me with searching for dates?
From: Voltane25 Apr 2011 16:32
To: Ken (SHIELDSIT) 94 of 101
I think it's a tall order asking Pete to find one date, let alone two...
From: Ken (SHIELDSIT)25 Apr 2011 16:33
To: Voltane 95 of 101

:')

 

Pete is a sexy man, he probably gets a lot of tail! (angel)

From: Ken (SHIELDSIT)25 Apr 2011 17:05
To: Voltane 96 of 101
I take that back! I got my query sorted on my own so Peter is no longer sexy!
From: Peter (BOUGHTONP)25 Apr 2011 19:39
To: Ken (SHIELDSIT) 97 of 101
Hey! :'(
From: Ken (SHIELDSIT)25 Apr 2011 20:05
To: Peter (BOUGHTONP) 98 of 101
(hug)
From: Ken (SHIELDSIT)26 Apr 2011 15:09
To: Peter (BOUGHTONP) 99 of 101

Pete do you know of a way to do this:

 

Say one of my users generates a report. I then ask them to add it to the monthly report. If they forget or something I want it to warn them if they click the back button or close the browser. Is there some Java or CF code that will do that?