Wednesday, March 28, 2012
Help with SQL Function
From the Following Table, I want to enter a Temperature and then have the
SQL Function Return the Web Color
-- TemperatureIndex --
ID TempMin TempMax WebColor
1 0 9 #E59DCB
2 10 19 #8569FA
3 20 29 #3F9CFB
4 30 39 #73E96F
I would like to Enter a Temperature and return the following WebColor output
15 -> #E59DCB
28 -> #3F9CFB
32 -> #73E96FCREATE TABLE TemperatureIndex
(
ID int NOT NULL,
TempMin int NOT NULL,
TempMax int NOT NULL,
WebColor char(7) NOT NULL
)
GO
INSERT INTO TemperatureIndex VALUES(1, 0, 9, '#E59DCB')
INSERT INTO TemperatureIndex VALUES(2, 10, 19, '#8569FA')
INSERT INTO TemperatureIndex VALUES(3, 20, 29, '#3F9CFB')
INSERT INTO TemperatureIndex VALUES(4, 30, 39, '#73E96F')
GO
CREATE UNIQUE CLUSTERED INDEX TemperatureIndex_cdx
ON TemperatureIndex(TempMin, TempMax)
GO
ALTER TABLE TemperatureIndex
ADD CONSTRAINT PK_TemperatureIndex
PRIMARY KEY NONCLUSTERED (ID)
GO
CREATE FUNCTION dbo.GetWebColorForTemperature(@.Temp int)
RETURNS char(7)
AS
BEGIN
RETURN (SELECT WebColor
FROM TemperatureIndex
WHERE @.Temp BETWEEN TempMin AND TempMax
)
END
GO
SELECT dbo.GetWebColorForTemperature(15)
SELECT dbo.GetWebColorForTemperature(28)
SELECT dbo.GetWebColorForTemperature(32)
GO
Hope this helps.
Dan Guzman
SQL Server MVP
"Stuart Shay" <sshay@.yahoo.com> wrote in message
news:uzg9rvG%23FHA.160@.TK2MSFTNGP12.phx.gbl...
> Hello All:
> From the Following Table, I want to enter a Temperature and then have the
> SQL Function Return the Web Color
> -- TemperatureIndex --
> ID TempMin TempMax WebColor
> 1 0 9 #E59DCB
> 2 10 19 #8569FA
> 3 20 29 #3F9CFB
> 4 30 39 #73E96F
> I would like to Enter a Temperature and return the following WebColor
> output
> 15 -> #E59DCB
> 28 -> #3F9CFB
> 32 -> #73E96F
>|||Dan:
Thanks for your help !!!
Best
Stuart
"Dan Guzman" <guzmanda@.nospam-online.sbcglobal.net> wrote in message
news:uev6wbH%23FHA.140@.TK2MSFTNGP12.phx.gbl...
> CREATE TABLE TemperatureIndex
> (
> ID int NOT NULL,
> TempMin int NOT NULL,
> TempMax int NOT NULL,
> WebColor char(7) NOT NULL
> )
> GO
> INSERT INTO TemperatureIndex VALUES(1, 0, 9, '#E59DCB')
> INSERT INTO TemperatureIndex VALUES(2, 10, 19, '#8569FA')
> INSERT INTO TemperatureIndex VALUES(3, 20, 29, '#3F9CFB')
> INSERT INTO TemperatureIndex VALUES(4, 30, 39, '#73E96F')
> GO
> CREATE UNIQUE CLUSTERED INDEX TemperatureIndex_cdx
> ON TemperatureIndex(TempMin, TempMax)
> GO
> ALTER TABLE TemperatureIndex
> ADD CONSTRAINT PK_TemperatureIndex
> PRIMARY KEY NONCLUSTERED (ID)
> GO
> CREATE FUNCTION dbo.GetWebColorForTemperature(@.Temp int)
> RETURNS char(7)
> AS
> BEGIN
> RETURN (SELECT WebColor
> FROM TemperatureIndex
> WHERE @.Temp BETWEEN TempMin AND TempMax
> )
> END
> GO
> SELECT dbo.GetWebColorForTemperature(15)
> SELECT dbo.GetWebColorForTemperature(28)
> SELECT dbo.GetWebColorForTemperature(32)
> GO
> --
> Hope this helps.
> Dan Guzman
> SQL Server MVP
> "Stuart Shay" <sshay@.yahoo.com> wrote in message
> news:uzg9rvG%23FHA.160@.TK2MSFTNGP12.phx.gbl...
>
Help with Sproc and multi parameter
I'm trying to build a sproc that will return rows even if some of the parameters are blank. For example; if a user does not enter a priority, a status, or a caller the sproce should still return rows based on the other parameters.
Can anyone help me find a way to modify my sproc bellow to allow this? I think the way I have it bellow will only return those rows where the user has entered a parameter or the record has a null in the field.
ALTER PROCEDURE dbo.ContactManagementAction(@.ClientIDint,@.Priorityint,@.TStartdatetime,@.TEnddatetime,@.Statusnvarchar,@.ConTypeIDint,@.Callernvarchar,@.Keywordnvarchar)ASSELECT Task_ID, ClientID, Priority, ActionDate, Subject, Note, Status, CompletionDate, TaskDocument, ReminderDate, Reminder, ReminderTime, Sol_ID, DateEntered, EnteredBy, Caller, ContactTypeID, DueDateFROM tblTasksWHERE (ClientID = @.ClientID)AND (Priority = @.Priority)OR (PriorityISNULL)AND (ActionDateBETWEEN @.TStartAND @.TEnd)AND (Status = @.Status)OR (StatusISNULL)AND (ContactTypeID = @.ConTypeID)OR (ContactTypeIDISNULL)AND (Caller = @.Caller)OR (CallerISNULL)AND (SubjectLIKE @.Keyword)OR (SubjectISNULL)RETURN
You have the query correct. Your OR's and AND's are misplaced around the brackets.
ALTER PROCEDURE dbo.ContactManagementAction(@.ClientIDint,@.Priorityint,@.TStartdatetime,@.TEnddatetime,@.Statusnvarchar,@.ConTypeIDint,@.Callernvarchar,@.Keywordnvarchar)ASBEGINSET NOCOUNT ONSELECTTask_ID, ClientID, Priority, ActionDate, Subject, Note, Status, CompletionDate, TaskDocument, ReminderDate, Reminder, ReminderTime, Sol_ID, DateEntered, EnteredBy, Caller, ContactTypeID, DueDateFROMtblTasksWHERE(ClientID = @.ClientID)AND (Priority = @.PriorityOR @.PriorityISNULL)AND (ActionDateBETWEEN @.TStartAND @.TEnd)AND (Status = @.StatusOR @.StatusISNULL)AND (ContactTypeID = @.ConTypeIDOR @.ContactTypeIDISNULL)AND (Caller = @.CallerOR @.CallerISNULL)AND (SubjectLIKE @.KeywordOR @.SubjectISNULL)SET NOCOUNT OFFEND|||
I tried it and I'm still not getting any rows returned. I have even tried it with all parameters having a good entry.
Just to be sure;
I should be able to enter a clientID, an ActionDate range, a priority, and the other fields of the table could have any entry or null for the other parameters and get returned, YES?
|||I did not notice it but try setting the length for your parameters.|||Besize the size, could the default values be the reason:
Like:
...
@.Statusnvarchar(50)=NULL,
@.ConTypeIDint=NULL,
@.Callernvarchar(50)=NULL,
@.Keywordnvarchar(50)=NULL
I really am stuck on this one. Can anyone offer any suggestions? Does anyone understand my problem with this?
|||
Hi
You could add default value to parameter as limno suggested.
If that doesn't work. You could try adding following code to your stored procedure and test in Sql Server Management Studio to trace each parameters.:
if (@.PriorityISNULL)begin print N'Priority IS NULL'endelsebegin print @.Priorityend--print other parameters in similar wayHope this helps.|||
So here is what I have, listed below: I should be able to pass in a clientID and a valid date range and it should not matter what is in the other fields because I'm passing in NULL, right?
ALTER PROCEDURE dbo.eP_BindContactManagementAction(@.ClientIDint,@.Prioritysmallint=NULL,@.TStartdatetime,@.TEnddatetime,@.Statusnvarchar(50)=NULL,@.ConTypeIDint=NULL,@.Callernvarchar(50)=NULL,@.Keywordnvarchar(50)=NULL)ASSELECT Task_ID, ClientID, Priority, ActionDate, Subject, Note, Status, CompletionDate, TaskDocument, ReminderDate, Reminder, ReminderTime, Sol_ID, DateEntered, EnteredBy, Caller, ContactTypeID, DueDateFROM tblTasksWHERE (ClientID = @.ClientID)AND (Priority = @.Priority)AND (ActionDateBETWEEN @.TStartAND @.TEnd)AND (Status = @.Status)AND (ContactTypeID = @.ConTypeID)AND (Caller = @.Caller)AND (SubjectLIKE @.Keyword)RETURNI appreciate any help,|||
You WHERE clause has problem to handle NULL values: Please try this one fromndinakar
SELECTTask_ID, ClientID, Priority, ActionDate, Subject, Note, Status, CompletionDate, TaskDocument,
ReminderDate, Reminder, ReminderTime, Sol_ID,
DateEntered, EnteredBy, Caller, ContactTypeID, DueDate
FROMtblTasks
WHERE(ClientID = @.ClientID)
AND (Priority = @.PriorityOR @.PriorityISNULL)
AND (ActionDateBETWEEN @.TStartAND @.TEnd)
AND (Status = @.StatusOR @.StatusISNULL)
AND (ContactTypeID = @.ConTypeIDOR @.ContactTypeIDISNULL)
AND (Caller = @.CallerOR @.CallerISNULL)
AND (SubjectLIKE @.KeywordOR @.SubjectISNULL)
|||
Another question: could you show us your datasource control code too? if you are using SQLDatasource control, you may need to set this CancelSelectOnNullParameter="false".
Just another shot in dark.
|||Here is the code, it will return a record if I make an entry for all parameters. But if I leave one blank no records are returned.
Sub BindData() Session("TaskStart") =Me.BasicDatePickerHStart.SelectedValue Session("TaskEnd") =Me.BasicDatePickerHEnd.SelectedValueDim TStartAs String = Session("TaskStart")Dim TEndAs String = Session("TaskEnd")Dim ConnectStrAs String = _ ConfigurationManager.ConnectionStrings("SQL2ConnectionString").ConnectionString'If user unchecks use due date sproc.Dim strSprocAs String strSproc ="BindContactManagementAction" MyConnection =New SqlConnection(ConnectStr) MyCommand =New SqlCommand(strSproc, MyConnection) MyCommand.CommandType = CommandType.StoredProcedureDim ClientIDParamAs New SqlParameter("@.ClientID", SqlDbType.Int, 4) MyCommand.Parameters.Add(ClientIDParam) ClientIDParam.Value = Session("lgClientID")Dim TaskStartParamAs New SqlParameter("@.TStart",Me.BasicDatePickerHStart.SelectedValue) MyCommand.Parameters.Add(TaskStartParam) TaskStartParam.Value =Me.BasicDatePickerHStart.SelectedValueDim TaskEndParamAs New SqlParameter("@.TEnd",Me.BasicDatePickerHEnd.SelectedValue) MyCommand.Parameters.Add(TaskEndParam) TaskEndParam.Value =Me.BasicDatePickerHEnd.SelectedValueIf String.IsNullOrEmpty(Me.KeyWordText.Text)Then Dim KeywordParamAs New SqlParameter("@.Keyword", DBNull.Value) MyCommand.Parameters.Add(KeywordParam) KeywordParam.Value =Me.KeyWordText.Text MsgBox(KeywordParam.Value)Else Dim KeywordParamAs New SqlParameter("@.Keyword",Me.KeyWordText.Text) MyCommand.Parameters.Add(KeywordParam) KeywordParam.Value =Me.KeyWordText.Text MsgBox(KeywordParam.Value)End If If String.IsNullOrEmpty(Me.StatusSearchDrop.SelectedItem.Text)Then Dim StatusParamAs New SqlParameter("@.Status", DBNull.Value) MyCommand.Parameters.Add(StatusParam) StatusParam.Value =Me.StatusSearchDrop.SelectedItem.Text MsgBox(StatusParam.Value)Else Dim StatusParamAs New SqlParameter("@.Status",Me.StatusSearchDrop.SelectedItem.Text) MyCommand.Parameters.Add(StatusParam) StatusParam.Value =Me.StatusSearchDrop.SelectedItem.Text MsgBox(StatusParam.Value)End If If String.IsNullOrEmpty(Me.PrioritySearchDrop.SelectedItem.Text)Then Dim PriorityParamAs New SqlParameter("@.Priority", DBNull.Value) MyCommand.Parameters.Add(PriorityParam) PriorityParam.Value =Me.PrioritySearchDrop.SelectedItem.Text MsgBox(PriorityParam.Value)Else Dim PriorityParamAs New SqlParameter("@.Priority",Me.PrioritySearchDrop.SelectedItem.Text) MyCommand.Parameters.Add(PriorityParam) PriorityParam.Value =Me.PrioritySearchDrop.SelectedItem.Text MsgBox(PriorityParam.Value)End If If String.IsNullOrEmpty(Me.CallerTextSearch.Text)Then Dim CallerParamAs New SqlParameter("@.Caller", DBNull.Value) MyCommand.Parameters.Add(CallerParam) CallerParam.Value =Me.CallerTextSearch.Text MsgBox(CallerParam.Value)Else Dim CallerParamAs New SqlParameter("@.Caller",Me.CallerTextSearch.Text) MyCommand.Parameters.Add(CallerParam) CallerParam.Value =Me.CallerTextSearch.Text MsgBox(CallerParam.Value)End If If String.IsNullOrEmpty(Me.ContactTypeSearchDrop.SelectedValue)Then Dim ConTypeIDParamAs New SqlParameter("@.ConTypeID", DBNull.Value) MyCommand.Parameters.Add(ConTypeIDParam) ConTypeIDParam.Value =Me.ContactTypeSearchDrop.SelectedValue MsgBox(ConTypeIDParam.Value)Else Dim ConTypeIDParamAs New SqlParameter("@.ConTypeID",Me.ContactTypeSearchDrop.SelectedValue) MyCommand.Parameters.Add(ConTypeIDParam) ConTypeIDParam.Value =Me.ContactTypeSearchDrop.SelectedValue MsgBox(ConTypeIDParam.Value)End If MyConnection.Open()Dim DSAs SqlDataReader = MyCommand.ExecuteReader(System.Data.CommandBehavior.CloseConnection) MyEditDataGrid.DataSource = DS MyEditDataGrid.DataBind()End Sub|||We have to find where the problem is:
1. Whether the Stored Procedure is running OK or not in your database?
2. If the sp can return records with limited parameters, we can focus on the code part.
PS:(this is a version I tested on my db which works)( By the way, I would use field name to Name parameters to avoid confusion, but this is not the problem here)
ALTER
PROCEDURE [dbo].[eP_BindContactManagementAction](
@.ClientID
int,@.Priority
smallint=NULL,@.TStart
datetime,@.TEnd
datetime,@.Status
nvarchar(50)=NULL,@.ConTypeID
int=NULL,@.Caller
nvarchar(50)=NULL,@.Keyword
nvarchar(50)=NULL)
AS
SELECT
Task_ID, ClientID, Priority, ActionDate, Subject, Note, Status, CompletionDate, TaskDocument,ReminderDate,Reminder
, ReminderTime, Sol_ID, DateEntered, EnteredBy, Caller, ContactTypeID, DueDateFROM
tblTasksWHERE
(ClientID= @.ClientID)AND
(Priority= @.PriorityOR @.PriorityISNULL)AND
(ActionDateBETWEEN @.TStartAND @.TEnd)AND
(Status= @.StatusOR @.StatusISNULL)AND
(ContactTypeID= @.ConTypeIDOR @.ConTypeIDISNULL)AND
(Caller= @.CallerOR @.CallerISNULL)AND
(SubjectLIKE @.KeywordOR @.KeywordISNULL)END
|||Ok, progress the sp is working in the database, I tested it in VS 2005 and it worked, so it must be in my code.
Any thoughts from my earlier post?
|||I changed all my parameters to the code type below and it is working now:
I very much appreciate your help!
If String.IsNullOrEmpty(Me.KeyWordText.Text)Then MyCommand.Parameters.AddWithValue("@.Keyword", DBNull.Value)Else MyCommand.Parameters.AddWithValue("@.Keyword",Me.KeyWordText.Text)End If If String.IsNullOrEmpty(Me.StatusSearchDrop.SelectedItem.Text)Then MyCommand.Parameters.AddWithValue("@.Status", DBNull.Value)Else MyCommand.Parameters.AddWithValue("@.Status",Me.StatusSearchDrop.SelectedItem.Text)End Ifsql
Friday, March 9, 2012
Help with query
Hi all,
I am trying to populate a Datagrid with one SQL query but I can't get it to work the way I want. I have a table where I enter prices of articles, but not just the latest price, I also leave old prices inside. This way I can generate history of price changes.
This DB table consists of the following fields:
ID
Item_ID
Vendor_ID
Price
Date
When I try to pull a list of vendors that offer a certain article and the latest price, I always get all the prices for all the dates.
Here is the query:
select id, Vendor_ID, Price from shop_item_prices where Item__ID=1 order by Price asc
So could someone please tell me what do I have to do to get only 1 record per vendor with the latest price?
Thank you.
SELECT sip.ID,sip.VendorID,sip.Price
FROM Shop_item_prices sip
JOIN (SELECT item_id,vendor_id,MAX(Date) AS mdate FROM shop_item_prices GROUP BY Item_id,vendor_id) t1 ON sip.item_id=t1.item_id AND sip.vendor_id=t1.vendor_id AND sip.Date=t1.mdate
WHER Item_ID=1
|||
Great, it works :)
Thank you.
Wednesday, March 7, 2012
help with percision? if you enter a number in the trillions such 9,999,999,999,999 .net or sql m
can you please explian this chart:
The operand expressions are denoted as expression e1, with precision p1 and scale s1, and expression e2, with precision p2 and scale s2. The precision and scale for any expression that is not decimal is the precision and scale defined for the data type of the expression.
e1 + e2
max(s1, s2) + max(p1-s1, p2-s2) + 1
max(s1, s2)
e1 - e2
max(s1, s2) + max(p1-s1, p2-s2) + 1
max(s1, s2)
e1 * e2
p1 + p2 + 1
s1 + s2
e1 / e2
p1 - s1 + s2 + max(6, s1 + p2 + 1)
max(6, s1 + p2 + 1)
e1 { UNION | EXCEPT | INTERSECT } e2
max(s1, s2) + max(p1-s1, p2-s2)
max(s1, s2)
* The result precision and scale have an absolute maximum of 38. When a result precision is greater than 38, the corresponding scale is reduced to prevent the integral part of a result from being truncated.
e1 = numeric(20,8)
e2 = numeric(20,8)
e1/e2
is this correct
max(6,s1 + p2 + 1)
8 + 20 + 1= 29 since under 38 use 29 scale
scale would be max(6,29) = 29 correct?
p1 - s1 + s2 + max(6, s1 + p2 + 1)
20 - 8 + 8 + 29 = 49 does that mean it truncate the least sugificant digits by 29 - 11 = 18 so the effective result should be numeric(38,18) or ##,###,###,###,###,###,###.000000000000000000 this does not seem to be what you get can some explain also we have seen that if you enter a number in the trillions such 9,999,999,999,999 neither .net or sql management studio cannot display the value?
I think you have it, though it turns out that the actual returned type is numeric(38,17). You can see this using a variant:
declare @.c sql_variant
declare @.a numeric(20,8) --set the datatypes here
declare @.b decimal(20,8) --set the datatypes here
set @.a = 1 --set a value here
set @.b = 1 --set a value here
select @.c = @.a / @.b --do the math
select cast(@.c as varchar(40)),
cast(sql_variant_property(@.c,'BaseType') as varchar(20)) + '(' +
cast(sql_variant_property(@.c,'Precision') as varchar(10)) + ',' +
cast(sql_variant_property(@.c,'Scale') as varchar(10)) + ')'
- -
1.000000000000000000 numeric(38,18)
Don't quite understand your issue with trillions (though you have to use 21,8 instead of 20, 8 for the datatype:
declare @.c sql_variant
declare @.a numeric(21,8) --set the datatypes here
set @.a = 9999999999999 --set a value here
select @.c = @.a
select cast(@.c as varchar(40)),
cast(sql_variant_property(@.c,'BaseType') as varchar(20)) + '(' +
cast(sql_variant_property(@.c,'Precision') as varchar(10)) + ',' +
cast(sql_variant_property(@.c,'Scale') as varchar(10)) + ')'
- -
9999999999999.00000000 numeric(21,8)
help with percision? if you enter a number in the trillions such 9,999,999,999,999 .net or s
can you please explian this chart:
The operand expressions are denoted as expression e1, with precision p1 and scale s1, and expression e2, with precision p2 and scale s2. The precision and scale for any expression that is not decimal is the precision and scale defined for the data type of the expression.
e1 + e2
max(s1, s2) + max(p1-s1, p2-s2) + 1
max(s1, s2)
e1 - e2
max(s1, s2) + max(p1-s1, p2-s2) + 1
max(s1, s2)
e1 * e2
p1 + p2 + 1
s1 + s2
e1 / e2
p1 - s1 + s2 + max(6, s1 + p2 + 1)
max(6, s1 + p2 + 1)
e1 { UNION | EXCEPT | INTERSECT } e2
max(s1, s2) + max(p1-s1, p2-s2)
max(s1, s2)
* The result precision and scale have an absolute maximum of 38. When a result precision is greater than 38, the corresponding scale is reduced to prevent the integral part of a result from being truncated.
e1 = numeric(20,8)
e2 = numeric(20,8)
e1/e2
is this correct
max(6,s1 + p2 + 1)
8 + 20 + 1= 29 since under 38 use 29 scale
scale would be max(6,29) = 29 correct?
p1 - s1 + s2 + max(6, s1 + p2 + 1)
20 - 8 + 8 + 29 = 49 does that mean it truncate the least sugificant digits by 29 - 11 = 18 so the effective result should be numeric(38,18) or ##,###,###,###,###,###,###.000000000000000000 this does not seem to be what you get can some explain also we have seen that if you enter a number in the trillions such 9,999,999,999,999 neither .net or sql management studio cannot display the value?
I think you have it, though it turns out that the actual returned type is numeric(38,17). You can see this using a variant:
declare @.c sql_variant
declare @.a numeric(20,8) --set the datatypes here
declare @.b decimal(20,8) --set the datatypes here
set @.a = 1 --set a value here
set @.b = 1 --set a value here
select @.c = @.a / @.b --do the math
select cast(@.c as varchar(40)),
cast(sql_variant_property(@.c,'BaseType') as varchar(20)) + '(' +
cast(sql_variant_property(@.c,'Precision') as varchar(10)) + ',' +
cast(sql_variant_property(@.c,'Scale') as varchar(10)) + ')'
- -
1.000000000000000000 numeric(38,18)
Don't quite understand your issue with trillions (though you have to use 21,8 instead of 20, 8 for the datatype:
declare @.c sql_variant
declare @.a numeric(21,8) --set the datatypes here
set @.a = 9999999999999 --set a value here
select @.c = @.a
select cast(@.c as varchar(40)),
cast(sql_variant_property(@.c,'BaseType') as varchar(20)) + '(' +
cast(sql_variant_property(@.c,'Precision') as varchar(10)) + ',' +
cast(sql_variant_property(@.c,'Scale') as varchar(10)) + ')'
- -
9999999999999.00000000 numeric(21,8)