Showing posts with label code. Show all posts
Showing posts with label code. Show all posts

Wednesday, March 28, 2012

Multi-table UDF not returning all rows

I've been tearing my hair out over this UDF. The code works within a
stored procedure and also run ad-hoc against the database, but does not
run properly within my UDF. We've been using the SP, but I do need a
UDF instead now.

All users, including branch office, sub-companies and companies and so
on up the lines are in the same table. I need a function which returns
a row for each level, eventually getting to the master company all the
way at the top, but this UDF acts as though it can't enter the loop and
only inserts the @.userID and @.branchID rows. I have played with the
WHILE condition to no avail.

Any ideas on what I am missing?

(Running against SQL Server 2000)
----------------

ALTER FUNCTION udfUplineGetCompany (@.userID int)

RETURNS @.upline table (companyID int, companyname varchar(100), info
varchar(100))
AS
BEGIN

DECLARE @.branchID int
DECLARE @.companyID int
DECLARE @.tempID int

--Insert the original user data
INSERT INTO @.upline
SELECT tblusersid, companyname, 'userID'
FROM tblusers
WHERE tblusersid = @.userid

SELECT @.branchID = tblUsers.tblUsersID
FROM tblUsers
INNER JOIN tblUsersUsersLnk
ON tblUsers.tblUsersID = tblUsersUsersLnk.tblUsersID_Parent
WHERE tblUsersUsersLnk.tblUsersID_Child = @.userid

--Up one level
INSERT INTO @.upline
SELECT tblusersid, companyname, 'branchID'
FROM tblusers
WHERE tblusersid = @.branchid

SET @.tempID = @.branchID

WHILE @.@.ROWCOUNT <> 0
BEGIN
SELECT @.companyID = tblUsers.tblUsersID
FROM tblUsers
INNER JOIN tblUsersUsersLnk
ON tblUsers.tblUsersID = tblUsersUsersLnk.tblUsersID_Parent
WHERE tblUsersUsersLnk.tblUsersID_Child = @.tempID
AND tblUsersId <> 6

--Insert a row for each level up
INSERT INTO @.upline
SELECT tblusersid, companyname, 'companyID'
FROM tblusers
WHERE tblusersid = @.companyID

SET @.tempID = @.companyID

END

RETURN

ENDWell, if I try to run in as an ad-hoc query, it doesn't run properly at
all.

The use of @.@.rowcount is bound to go wrong. Also, the INSERT into the
table variable will be executed regardless of a match (or miss) of the
parent selection.

You should check the @.@.rowcount immediately after the "SELECT @.CompanyID
= ..." statement. If you do not want to handle the @.@.rowcount result at
that point, then make sure you move the @.@.rowcount status to a variable
immediately after the SELECT statement.

Gert-Jan

P.S. If you have proper primary key/foreign keys in place, then joining
to the tblUsers table in the SELECT statement is unnecessary.

nicolec@.octitle.com wrote:
> I've been tearing my hair out over this UDF. The code works within a
> stored procedure and also run ad-hoc against the database, but does not
> run properly within my UDF. We've been using the SP, but I do need a
> UDF instead now.
> All users, including branch office, sub-companies and companies and so
> on up the lines are in the same table. I need a function which returns
> a row for each level, eventually getting to the master company all the
> way at the top, but this UDF acts as though it can't enter the loop and
> only inserts the @.userID and @.branchID rows. I have played with the
> WHILE condition to no avail.
> Any ideas on what I am missing?
> (Running against SQL Server 2000)
> ----------------
> ALTER FUNCTION udfUplineGetCompany (@.userID int)
> RETURNS @.upline table (companyID int, companyname varchar(100), info
> varchar(100))
> AS
> BEGIN
> DECLARE @.branchID int
> DECLARE @.companyID int
> DECLARE @.tempID int
> --Insert the original user data
> INSERT INTO @.upline
> SELECT tblusersid, companyname, 'userID'
> FROM tblusers
> WHERE tblusersid = @.userid
> SELECT @.branchID = tblUsers.tblUsersID
> FROM tblUsers
> INNER JOIN tblUsersUsersLnk
> ON tblUsers.tblUsersID = tblUsersUsersLnk.tblUsersID_Parent
> WHERE tblUsersUsersLnk.tblUsersID_Child = @.userid
> --Up one level
> INSERT INTO @.upline
> SELECT tblusersid, companyname, 'branchID'
> FROM tblusers
> WHERE tblusersid = @.branchid
> SET @.tempID = @.branchID
> WHILE @.@.ROWCOUNT <> 0
> BEGIN
> SELECT @.companyID = tblUsers.tblUsersID
> FROM tblUsers
> INNER JOIN tblUsersUsersLnk
> ON tblUsers.tblUsersID = tblUsersUsersLnk.tblUsersID_Parent
> WHERE tblUsersUsersLnk.tblUsersID_Child = @.tempID
> AND tblUsersId <> 6
> --Insert a row for each level up
> INSERT INTO @.upline
> SELECT tblusersid, companyname, 'companyID'
> FROM tblusers
> WHERE tblusersid = @.companyID
> SET @.tempID = @.companyID
> END
> RETURN
> END|||Sometimes you look at something SO long you don't see the obvious...
thanks for the pointer, that worked perfect. For future newsgroup
reference, the new function text is at the bottom.

>P.S. If you have proper primary key/foreign keys in place, then joining
to the tblUsers table in the SELECT statement is unnecessary.

No keys anywhere in this database and it's driving me nuts. Every join
must be explicit.

----------------

ALTER FUNCTION udfUplineGetCompany (@.userID int)

RETURNS @.upline table (companyID int, companyname varchar(100), info
varchar(100), rows int)
AS
BEGIN

DECLARE @.branchID int
DECLARE @.companyID int
DECLARE @.tempID int
DECLARE @.rows int

SET @.rows = 1

INSERT INTO @.upline
SELECT tblusersid, companyname, 'userID', @.rows
FROM tblusers
WHERE tblusersid = @.userid

SELECT @.branchID = tblUsers.tblUsersID
FROM tblUsers
INNER JOIN tblUsersUsersLnk
ON tblUsers.tblUsersID = tblUsersUsersLnk.tblUsersID_Parent
WHERE tblUsersUsersLnk.tblUsersID_Child = @.userid

INSERT INTO @.upline
SELECT tblusersid, companyname, 'branchID', @.rows
FROM tblusers
WHERE tblusersid = @.branchid

SET @.tempID = @.branchID

WHILE @.rows = 1
BEGIN
SELECT @.companyID = tblUsers.tblUsersID
FROM tblUsers
INNER JOIN tblUsersUsersLnk
ON tblUsers.tblUsersID = tblUsersUsersLnk.tblUsersID_Parent
WHERE tblUsersUsersLnk.tblUsersID_Child = @.tempID
AND tblUsersId <> 6

SET @.rows = @.@.rowcount

INSERT INTO @.upline
SELECT tblusersid, companyname, 'companyID', @.rows
FROM tblusers
WHERE tblusersid = @.companyID
AND @.rows = 1

SET @.tempID = @.companyID

END

RETURN

END

Wednesday, March 21, 2012

Multiple while fetch cursor code

I seem to have a few problems with the below double cursor procedure. Probably due to the fact that I have two while loops based on fetch status. Or?

What I want to do is select out a series of numbers in medlemmer_cursor(currently set to only one number, for which I know I get results) and for each of these numbers select their MCPS code and gather these in a single string.

For some reason the outpiut (the insert into statement) returns the correct number 9611 but the second variable @.instrumentlinje remains empty.

If I test the select clause for 9611, it gets 4 lines. So to me its like the "SELECT @.instrumentlinje = @.instrumentlinje + ' ' + @.instrument" statement doesn't execute.

DELETE FROM ALL_tbl_instrumentkoder

DECLARE @.medlem int
DECLARE @.instrument varchar(10)
DECLARE @.instrumentlinje varchar(150)

DECLARE medlemmer_cursor CURSOR FOR
SELECT medlemsnummer
FROM ket.ALL_tbl_medlemsinfo (NOLOCK)
WHERE medlemsnummer = 9611

DECLARE instrumenter_cursor CURSOR FOR
SELECT [MCPS Kode]
FROM Gramex_DW.dbo.Instrumentlinie (NOLOCK)
WHERE Medlemsnummer = @.medlem

OPEN medlemmer_cursor

FETCH NEXT FROM medlemmer_cursor INTO @.medlem

WHILE @.@.FETCH_STATUS = 0
BEGIN

OPEN instrumenter_cursor
FETCH NEXT FROM instrumenter_cursor INTO @.instrument

WHILE @.@.FETCH_STATUS = 0
BEGIN
SELECT @.instrumentlinje = @.instrumentlinje + ' ' + @.instrument
FETCH NEXT FROM instrumenter_cursor INTO @.instrument
END

CLOSE instrumenter_cursor

INSERT INTO ALL_tbl_instrumentkoder VALUES(@.medlem, @.instrumentlinje)

FETCH NEXT FROM medlemmer_cursor INTO @.medlem

END

CLOSE medlemmer_cursor
DEALLOCATE medlemmer_cursor
DEALLOCATE instrumenter_cursorWell, I suspect the problem is related to referencing a variable in your cursor definition, but you shouldn't be using a cursor anyway.

Here is a simpler (non-cursor) method:

First, create this function:
create function dbo.instrumentlinje(@.medlem int)
returns varchar(4000) as
begin
declare @.instrumentlinje
select @.instrumentlinje = isnull(@.instrumentlinje + ' ', '') + MCPS Kode
from Gramex_DW.dbo.Instrumentlinie (NOLOCK)
WHERE Medlemsnummer = @.medlem

return @.instrumentlinje
end

Then, run this code:
insert into ALL_tbl_instrumentkoder
(medlem,
instrumentlinje)
select medlemsnummer,
dbo.instrumentlinje(medlem)
FROM ket.ALL_tbl_medlemsinfo (NOLOCK)
WHERE medlemsnummer = 9611

Warning! Not tested for syntax errors, and you may need to edit object ownership.|||Basically the same way I did it in Access.. just a greenhorn when it comes to SQL-server.

Thanks man :-)|||TSQL is similar to Access SQL, though there are a few syntactical differences. The concept of avoiding cursors and loops in favor of set-based operations is the same, though.

Friday, March 9, 2012

Multiple SuccessValues for ExecuteProcess task?

I have an execute process task to run Red-Gate's SqlDataCompare synchronization. The normal exit code is 0 indicating successful synchronization. However, if the tables are already identical and require no synchronization the process exit code is 63 and the task fails. I do not want the task to fail if the tables are identical, but it seems I can only specify a single value in the task's SuccessValue property. I tried separating values with a comma, e.g. 0,63. Any suggestions?

You could use the ForceExecutionResult property to ensure the task succeeds.

Donald

|||Thanks Donald. I was avoiding having to force the result since I want the task to fail if the exit code is other than 0 or 63. Do you think in a future version we might be able to specify multiple success values? (I entered it in connect.microsoft.com/SQLServer/Feedback).

Saturday, February 25, 2012

Multiple selection in a paramter?

I need a report (VS2005) that will select multiple records, such as:
Select * from CrimCase where Docket in (?). There is already code to
return a string of Dockets (pretty complex) so it would be easier to
just pass that along than to try to duplicate the code in SQL.
I tried setting the Report Parameter to Multi-Value but that doesn't
work. I have no idea how to pass in the parameter but this does work:
Select * from CrimCase where Docket in ('2006NY031095','2006NY024091')
When I replace the string with ? and get prompted for a parameter, it
does not work.
Any suggestions appreciated.On Feb 20, 9:31 am, dgk <d...@.somewhere.com> wrote:
> I need a report (VS2005) that will select multiple records, such as:
> Select * from CrimCase where Docket in (?). There is already code to
> return a string of Dockets (pretty complex) so it would be easier to
> just pass that along than to try to duplicate the code in SQL.
> I tried setting the Report Parameter to Multi-Value but that doesn't
> work. I have no idea how to pass in the parameter but this does work:
> Select * from CrimCase where Docket in ('2006NY031095','2006NY024091')
> When I replace the string with ? and get prompted for a parameter, it
> does not work.
> Any suggestions appreciated.
If you are referring to linking a multi-value parameter to a stored
procedure, you will want to select the Data tab >> select Edit
Selected Dataset [...] >> select the Parameters tab >> set Parameter
Name = @.Docket and set Parameter Value to an expression similar to
this: =Join(Parameters!Docket.Value, ","). Hope this helps.
Regards,
Enrique Martinez
Sr. Software Consultant|||On Wed, 20 Feb 2008 18:51:47 -0800 (PST), EMartinez
<emartinez.pr1@.gmail.com> wrote:
>On Feb 20, 9:31 am, dgk <d...@.somewhere.com> wrote:
>> I need a report (VS2005) that will select multiple records, such as:
>> Select * from CrimCase where Docket in (?). There is already code to
>> return a string of Dockets (pretty complex) so it would be easier to
>> just pass that along than to try to duplicate the code in SQL.
>> I tried setting the Report Parameter to Multi-Value but that doesn't
>> work. I have no idea how to pass in the parameter but this does work:
>> Select * from CrimCase where Docket in ('2006NY031095','2006NY024091')
>> When I replace the string with ? and get prompted for a parameter, it
>> does not work.
>> Any suggestions appreciated.
>
>If you are referring to linking a multi-value parameter to a stored
>procedure, you will want to select the Data tab >> select Edit
>Selected Dataset [...] >> select the Parameters tab >> set Parameter
>Name = @.Docket and set Parameter Value to an expression similar to
>this: =Join(Parameters!Docket.Value, ","). Hope this helps.
>
Not exactly, since it isn't going to a stored procedure; the SQL is
text. But, I didn't know about that parameter tab, nor that I could
put in a more complex expression. I'm not sure how to interact with
the SSRS engine. I really want the query to end up constructing OR
statements - ie, Select * from LawCases where Docket = 1112222 or
docket = 444232 or docket = 777333, extending the query depending on
the actual number of docket numbers passed in the one parameter.
I think a more acceptable way is to just create a temporary table,
putting in the cases that I want reported on, and then call SSRS,
taking all the cases in that table.
I'm intrigued by what I can do with the code though. Is it possible to
write code in the Custom Code section that will actually construct the
query on the fly, or is that code only for calling once the query has
returned and the records are being processed?|||First, it looks like you are using ODBC (hence the ? in your query). No
problem, just that when you map query parameters to report parameters it is
order dependent (i.e. the order your ? come in your query).
The following query will work for you:
Select * from LawCases where Docket in (?)
Then in layout, Report Menu-> Report Parameters set this parameter as
multi-value.
For testing, put in the appropriate values in available values. Do not put
quotes (single or double). Make sure the data type of the parameter is
string.
Put this in for available values:
Label Value
Case1 2006NY031095
Case2 2006NY024091
After you get this working then add whatever parameters you need to have
another dataset that creates this list of dockets. For instance, add your
date range and the other dataset uses the data range to return the dockets.
Bruce Loehle-Conger
MVP SQL Server Reporting Services
"dgk" <dgk@.somewhere.com> wrote in message
news:912rr3hcfe43pt8ri4fm580tanniajmhd3@.4ax.com...
> On Wed, 20 Feb 2008 18:51:47 -0800 (PST), EMartinez
> <emartinez.pr1@.gmail.com> wrote:
>>On Feb 20, 9:31 am, dgk <d...@.somewhere.com> wrote:
>> I need a report (VS2005) that will select multiple records, such as:
>> Select * from CrimCase where Docket in (?). There is already code to
>> return a string of Dockets (pretty complex) so it would be easier to
>> just pass that along than to try to duplicate the code in SQL.
>> I tried setting the Report Parameter to Multi-Value but that doesn't
>> work. I have no idea how to pass in the parameter but this does work:
>> Select * from CrimCase where Docket in ('2006NY031095','2006NY024091')
>> When I replace the string with ? and get prompted for a parameter, it
>> does not work.
>> Any suggestions appreciated.
>>
>>If you are referring to linking a multi-value parameter to a stored
>>procedure, you will want to select the Data tab >> select Edit
>>Selected Dataset [...] >> select the Parameters tab >> set Parameter
>>Name = @.Docket and set Parameter Value to an expression similar to
>>this: =Join(Parameters!Docket.Value, ","). Hope this helps.
> Not exactly, since it isn't going to a stored procedure; the SQL is
> text. But, I didn't know about that parameter tab, nor that I could
> put in a more complex expression. I'm not sure how to interact with
> the SSRS engine. I really want the query to end up constructing OR
> statements - ie, Select * from LawCases where Docket = 1112222 or
> docket = 444232 or docket = 777333, extending the query depending on
> the actual number of docket numbers passed in the one parameter.
> I think a more acceptable way is to just create a temporary table,
> putting in the cases that I want reported on, and then call SSRS,
> taking all the cases in that table.
> I'm intrigued by what I can do with the code though. Is it possible to
> write code in the Custom Code section that will actually construct the
> query on the fly, or is that code only for calling once the query has
> returned and the records are being processed?

Monday, February 20, 2012

multiple rows and columns MAX

Hi All,
I'm using the sample table:

ID | CODE | V1 | V2 | V3
--------------------
1 3 10 3 43
1 4 9 8 22
1 2 6 2 55
1 5 57 12 6

I want to get for a given ID the MAX(V1), MAX(V2), MAX(V3)
and their respective CODEs.

For the above table the returned record for ID=1 should be:
v1=57, v2=12, v3=55, code_v1=5, code_v2=5, code_v3=2

currently I've got a very messy solution, I'm
looking for an elegant way to do this.

10x,
Assaf.You do not say how you want to hand duplicates, where the same value
is the max for more than one code.

SELECT X.*,
(select min(CODE) from Whatever as W1
where W1.ID = X.ID
and W1.V1 = X.V1) as code_v1,
(select min(CODE) from Whatever as W2
where W2.ID = X.ID
and W2.V2 = X.V1) as code_v2,
(select min(CODE) from Whatever as W3
where W3.ID = X.ID
and W3.V3 = X.V3) as code_v3
FROM (select ID, max(V1) as V1, max(V2) as V2, max(V3) as V3
from Whatever
group by ID) as X

Roy Harvey
Beacon Falls, CT

On 3 Jul 2006 06:20:33 -0700, stassaf@.gmail.com wrote:

Quote:

Originally Posted by

>Hi All,
>I'm using the sample table:
>
>ID | CODE | V1 | V2 | V3
>--------------------
>1 3 10 3 43
>1 4 9 8 22
>1 2 6 2 55
>1 5 57 12 6
>
>I want to get for a given ID the MAX(V1), MAX(V2), MAX(V3)
>and their respective CODEs.
>
>For the above table the returned record for ID=1 should be:
>v1=57, v2=12, v3=55, code_v1=5, code_v2=5, code_v3=2
>
>currently I've got a very messy solution, I'm
>looking for an elegant way to do this.
>
>10x,
>Assaf.

|||Hi Roy,

10x for your prompt reply.
lets say duplicates are allowed, how can i simplify the solutions?

Regards,
Assaf.

Roy Harvey wrote:

Quote:

Originally Posted by

You do not say how you want to hand duplicates, where the same value
is the max for more than one code.
>
>
SELECT X.*,
(select min(CODE) from Whatever as W1
where W1.ID = X.ID
and W1.V1 = X.V1) as code_v1,
(select min(CODE) from Whatever as W2
where W2.ID = X.ID
and W2.V2 = X.V1) as code_v2,
(select min(CODE) from Whatever as W3
where W3.ID = X.ID
and W3.V3 = X.V3) as code_v3
FROM (select ID, max(V1) as V1, max(V2) as V2, max(V3) as V3
from Whatever
group by ID) as X
>
Roy Harvey
Beacon Falls, CT
>
On 3 Jul 2006 06:20:33 -0700, stassaf@.gmail.com wrote:
>

Quote:

Originally Posted by

Hi All,
I'm using the sample table:

ID | CODE | V1 | V2 | V3
--------------------
1 3 10 3 43
1 4 9 8 22
1 2 6 2 55
1 5 57 12 6

I want to get for a given ID the MAX(V1), MAX(V2), MAX(V3)
and their respective CODEs.

For the above table the returned record for ID=1 should be:
v1=57, v2=12, v3=55, code_v1=5, code_v2=5, code_v3=2

currently I've got a very messy solution, I'm
looking for an elegant way to do this.

10x,
Assaf.

|||>lets say duplicates are allowed, how can i simplify the solutions?

The example I posted handles duplicates by returning the smallest,
min(CODE). Returning the largest would be easy enough, max(CODE).

Anything else woule become more complicated. Otherwise I think that
pretty much IS the simple solution! 8-)

Roy

On 3 Jul 2006 06:54:11 -0700, stassaf@.gmail.com wrote:

Quote:

Originally Posted by

>Hi Roy,
>
>10x for your prompt reply.
>lets say duplicates are allowed, how can i simplify the solutions?
>
>Regards,
>Assaf.
>
>Roy Harvey wrote:

Quote:

Originally Posted by

>You do not say how you want to hand duplicates, where the same value
>is the max for more than one code.
>>
>>
>SELECT X.*,
> (select min(CODE) from Whatever as W1
> where W1.ID = X.ID
> and W1.V1 = X.V1) as code_v1,
> (select min(CODE) from Whatever as W2
> where W2.ID = X.ID
> and W2.V2 = X.V1) as code_v2,
> (select min(CODE) from Whatever as W3
> where W3.ID = X.ID
> and W3.V3 = X.V3) as code_v3
> FROM (select ID, max(V1) as V1, max(V2) as V2, max(V3) as V3
> from Whatever
> group by ID) as X
>>
>Roy Harvey
>Beacon Falls, CT
>>
>On 3 Jul 2006 06:20:33 -0700, stassaf@.gmail.com wrote:
>>

Quote:

Originally Posted by

>Hi All,
>I'm using the sample table:
>
>ID | CODE | V1 | V2 | V3
>--------------------
>1 3 10 3 43
>1 4 9 8 22
>1 2 6 2 55
>1 5 57 12 6
>
>I want to get for a given ID the MAX(V1), MAX(V2), MAX(V3)
>and their respective CODEs.
>
>For the above table the returned record for ID=1 should be:
>v1=57, v2=12, v3=55, code_v1=5, code_v2=5, code_v3=2
>
>currently I've got a very messy solution, I'm
>looking for an elegant way to do this.
>
>10x,
>Assaf.