I am trying to get the folders name which are in the subfolders.
Example:
folder_id folder_name parent_folder_id
1 F1 0
2 F2 1
3 F3 2
4 F4 3
Now I am trying to get the f4 name along with the parent folder name like :F1/F2/F3/F4
I am getting the parent_folder_id based on folder_id and wrote the loop condition,Here is my function.
for vrecord in (select parent_folder_id from public."VOfficeApp_filefolder"
where folder_id = ip_folder_id)
loop
return query
select (SELECT array_to_json(array_agg(row_to_json(b))) FROM
(select folder_name from public."VOfficeApp_filefolder"
where folder_id = v_id)b)as path;
end loop;
Aggregate functions do not build hierarchical results; for that you need a RECURSIVE CTE. Once the hierarchy is built you can then convert to json. The following function does that. The function takes the folder name you are interested in, after all it only used at the last minuet anyway to eliminate the rest of the hierarchy that as built.
create or replace function path_to_folder(target_folder_name text)
returns json
language sql
as $$
with recursive folder_path (id, folder_name, path) as
( select folder_id, folder_name,folder_name || '/'
from folders
where parent_folder_id = 0
union all
select f.folder_id, f.folder_name, fp.path || f.folder_name || '/'
from folders f
join folder_path fp on (f.parent_folder_id = fp.id)
)
, bjc (folder_name, path) as
( select folder_name, path
from folder_path
where folder_name = target_folder_name
) -- select * from bjc;
select json_agg(row_to_json((folder_name, path)))
from bjc
group by folder_name;
$$;
Note: the second cte bjc (Before Json Conversion) is probably not needed, but as I hate json (imho a complexity I'd rather not deal with). You could move the where clause from it into the json construction. But I always like to see results before converting.
Side Note:
Postgres 9.2 is obsolete. Having gone out of support in Nov, 2017. You seriously should update.
For Iseries/IBMi DB2.
I am joining multiple files/tables together.
I have written the code in both DDS and SQL.
The DDS Logical File is working exactly as expected, but I can not use it for embedded sql in rpgle as it then defaults to the SQE engine resulting in horrendous performance.
The SQL view, on the other hand had NULLs until I used IFNULL( MBRDESCR, ''). But now MBRDECSR is a VARCHAR. Which is unacceptable.
So how do I create a SQL join without NULLs and VARCHARs?
Requested Sample Code:
DDS:
JDFTVAL
R TRANSR JFILE(TRANSPF MBRPF)
J JOIN(1 2)
JFLD(MBRID MBRID)
*
TRANSID JREF(1)
MBRID JREF(1)
MBRNAME JREF(2)
MBRSURNME JREF(2)
*
K TRANSID
K MBRID
SQL:
CREATE VIEW TRANSV01 AS (
SELECT TRANSID ,
MBRID ,
CAST(IFNULL(MBRNAME , '') as Char(20)) ,
CAST(IFNULL(MBRSURNME, '') as Char(25))
FROM TRANSPF
--Member Name
LEFT OUTER JOIN MBRPF on MBRID = MBRID
) RCDFMT TRANSR;
Please note the following:
Example above is simplified
Not every MBRID in the TRANSPF has a corresponding entry in the MBRPF (ie. no referential constraint). Thus when MBRPF is joined to the TRANSPF, there will be NULL values in MBRNAME, MBRSURNME. Unless JDFTVAL or IFNULL() is used.
I prefer not to have a VARCHAR, because of performance and extname() in rpgle.
I prefer not to have NULL values, I do not want the pgm to have to handle them.
Assuming it's the 'Allows the null value' that you find undesirable, use a UNION. The first SELECT chooses all the rows that match, which will set the NOT NULL property for you. The second SELECT chooses all the rows that don't have a match - you provide filler fields for those.
CREATE VIEW TRANSV01 AS (
SELECT TRANSID ,
MBRID ,
MBRNAME ,
MBRSURNME
FROM TRANSPF
--Member Name
JOIN MBRPF on MBRID = MBRID
UNION
SELECT TRANSID ,
MBRID ,
CAST('') as Char(20)) ,
CAST('') as Char(25))
FROM TRANSPF
--Member Name
EXCEPTION JOIN MBRPF on MBRID = MBRID
) RCDFMT TRANSR;
My query has too many subqueries and each query has repeated parameters. How to design the report in eclipse. This is my query
SELECT
C.COMP_CODE,C.MATCODE,C.ATTRIB1,C.ATTRIB2,C.MAT_NAME,C.SUP_PROD_CODE,
C.SUP_CODE,C.BRAND_CODE,C.CAT_CODE,SGRPCODE,SUB_SGRPCODE,C.UNIT_CODE,
NVL(SUM(D.SALES_QTY),0)SALES_QTY,
NVL(SUM(D.SALES_VAL),0) SALES_VAL,
MAX(COST_PRICE) GRN_COST_PRICE,GRN_DATE,'sales qty' a, 'sales val' b,'stock' c,'stock val' d
FROM
(
SELECT A.COMP_CODE,A.MATCODE,B.UNIT_CODE,A.ATTRIB1,A.ATTRIB2,MAT_NAME,SUP_PROD_CODE,
SUP_CODE,BRAND_CODE,CAT_CODE,SGRPCODE,SUB_SGRPCODE,COST_PRICE,GRN_DATE FROM
(
SELECT A.COMP_CODE,A.MATCODE,A.ATTRIB1,A.ATTRIB2,MAT_NAME,SUP_PROD_CODE,
SUP_CODE,BRAND_CODE,CAT_CODE,SGRPCODE,SUB_SGRPCODE,B.COST_PRICE,B.GRN_DATE FROM
(
SELECT A.COMP_CODE,A.MATCODE,A.ATTRIB1,A.ATTRIB2,B.MAT_NAME,B.SUP_PROD_CODE,
B.SUP_CODE,B.BRAND_CODE,B.CAT_CODE,B.SGRPCODE,B.SUB_SGRPCODE FROM
MAT_LIST A,
MATERIAL_MASTER B
WHERE A.COMP_CODE=B.COMP_CODE
AND A.MATCODE=B.MATCODE
--AND A.MATCODE='168847'
)A,
(SELECT A.COMP_CODE,A.MAIN_CODE,A.MATCODE,NVL(A.ATTRIB_CODE1,0) ATTRIB1,NVL(A.ATTRIB_CODE2,0) ATTRIB2,
A.MAT_TYPE,MAX(A.MAT_COST) COST_PRICE,GRN_DATE
FROM INV_GRN_DTL_V A
WHERE a.grn_date=(select max(b.grn_date) from inv_grn_dtl_v b
where b.comp_code=a.comp_code and
b.main_code=a.main_code and
b.matcode=a.matcode and
nvl(b.grn_status,'P')='A' and
nvl(b.auth_status,'P')='A' and
b.supcode<>'GDS1' and
b.grn_date<=:TO_DT)
AND NVL(A.GRN_STATUS,'P')='A'
AND NVL(A.AUTH_STATUS,'P')='A'
GROUP BY A.COMP_CODE,A.MAIN_CODE,A.MATCODE,A.ATTRIB_CODE1,A.ATTRIB_CODE2,A.MAT_TYPE,GRN_DATE
) B
WHERE A.COMP_CODE=B.COMP_CODE(+)
AND A.MATCODE=B.MATCODE(+)
AND A.ATTRIB1=B.ATTRIB1(+)
AND A.ATTRIB2=B.ATTRIB2(+)
AND A.COMP_CODE=:P_COMP_CODE)
A,(
SELECT COMP_CODE,MAIN_CODE,UNIT_CODE
FROM UNIT_MST WHERE COMP_CODE=56
AND UNIT_CODE IN (SELECT DISTINCT UNIT_CODE FROM STK_SALES_VU
WHERE ORD_DATE BETWEEN :FR_DT AND :TO_DT
AND COMP_CODE=:P_COMP_CODE)
--UNION ALL
--SELECT DISTINCT COMP_CODE,MAIN_CODE,'STOCK' FROM UNIT_MST WHERE COMP_CODE=:P_COMP_CODE
) B
WHERE A.COMP_CODE=B.COMP_CODE
AND A.COMP_CODE=:P_COMP_CODE
AND UNIT_CODE=DECODE(:P_UNIT_CODE,'ALL',UNIT_CODE,:P_UNIT_CODE)
AND CAT_CODE BETWEEN DECODE(:FR_CAT,'ALL',CAT_CODE,:FR_CAT)
AND DECODE(:TO_CAT,'ALL',CAT_CODE,:TO_CAT)
AND SUP_CODE=DECODE(:P_SUP_CODE,'ALL',SUP_CODE,:P_SUP_CODE))
C,(
SELECT COMP_CODE,MAIN_CODE,UNIT_CODE,MAT_TYPE,MATCODE,NVL(ATTRIB_CODE1,0) ATTRIB_CODE1,NVL(ATTRIB_CODE2,0) ATTRIB_CODE2,
NVL(SUM(SALES_QTY),0) SALES_QTY, SUM(COST_VAL) SALES_VAL
FROM
(
SELECT COMP_CODE,MAIN_CODE,UNIT_CODE,MAT_TYPE,MATCODE,NVL(B.ATTRIB_CODE1,0) ATTRIB_CODE1,NVL(B.ATTRIB_CODE2,0) ATTRIB_CODE2,
NVL(SUM(B.SALE_QTY),0) SALES_QTY, SUM(B.VAL) COST_VAL
FROM STK_SALES_VU_ATT B
WHERE ORD_DATE BETWEEN :FR_DT AND :TO_DT
AND UNIT_CODE=DECODE(:P_UNIT_CODE,'ALL',UNIT_CODE,:P_UNIT_CODE)
AND COMP_CODE=:P_COMP_CODE
GROUP BY COMP_CODE,MAIN_CODE,UNIT_CODE,MAT_TYPE,MATCODE,NVL(B.ATTRIB_CODE1,0),NVL(B.ATTRIB_CODE2,0)
UNION ALL
SELECT COMP_CODE,MAIN_CODE,'STOCK' UNIT_CODE,MAT_TYPE,MATCODE,NVL(ATTRIB_CODE1,0),NVL(ATTRIB_CODE2,0),SUM(INC_QTY)-SUM(DEC_QTY) OB_QTY, 0 SALES_VAL
FROM INV_TRN_DAY_SUM_VU_ATT
WHERE TRN_DATE BETWEEN :FR_DT AND :TO_DT
AND UNIT_CODE=DECODE(:P_UNIT_CODE,'ALL',UNIT_CODE,:P_UNIT_CODE)
AND COMP_CODE=:P_COMP_CODE
GROUP BY COMP_CODE,MAIN_CODE,MAT_TYPE,MATCODE,NVL(ATTRIB_CODE1,0),NVL(ATTRIB_CODE2,0)
UNION ALL
SELECT COMP_CODE,MAIN_CODE,'STOCK' UNIT_CODE,MAT_TYPE,MATCODE,NVL(ATTRIB_CODE1,0),NVL(ATTRIB_CODE2,0),SUM(QTY)QTY, 0 SALES_VAL
FROM MATERIAL_DETAIL
WHERE SERIAL=:P_FNYR
AND UNIT_CODE=DECODE(:P_UNIT_CODE,'ALL',UNIT_CODE,:P_UNIT_CODE)
AND COMP_CODE=:P_COMP_CODE
GROUP BY COMP_CODE,MAIN_CODE,MAT_TYPE,MATCODE,NVL(ATTRIB_CODE1,0),NVL(ATTRIB_CODE2,0)
)
--WHERE MATCODE='168847'
GROUP BY COMP_CODE,MAIN_CODE,UNIT_CODE,MAT_TYPE,MATCODE,ATTRIB_CODE1,ATTRIB_CODE2
) D
WHERE C.COMP_CODE = D.COMP_CODE (+)
AND C.UNIT_CODE = D.UNIT_CODE(+)
AND C.MATCODE = D.MATCODE(+)
--AND C.MATCODE='168847'
AND C.ATTRIB1 = D.ATTRIB_CODE1(+)
AND C.ATTRIB2 = D.ATTRIB_CODE2(+)
AND C.COMP_CODE=:P_COMP_CODE
AND C.UNIT_CODE=DECODE(:P_UNIT_CODE,'ALL',C.UNIT_CODE,:P_UNIT_CODE)
GROUP BY
C.COMP_CODE,C.MATCODE,C.ATTRIB1,C.ATTRIB2,C.MAT_NAME,C.SUP_PROD_CODE,
C.SUP_CODE,C.BRAND_CODE,C.CAT_CODE,SGRPCODE,SUB_SGRPCODE,C.UNIT_CODE,GRN_DATE
order by c.unit_code
The parameters are (:FR_DT,:TO_DT, : p_COMP_CODE, :FR_CAT, :TO_CAT, : p_SUP_CODE) which need to be replaced with '?' while writing the query in dataset. But i don't know how to replace same parameter which is occurring at multiple places with the query parameters. and How to handle DECODE and between parametes.
One option is to use a WITH clause to assign your parameters to a dummy table.
WITH tmp_parms AS (
SELECT ? as fr_dt, ? as to_dt, ? as p_comp_code,
? as fr_cat, ? as to_cat, ? as p_sub_code
FROM dual
)
SELECT C.COMP_CODE,C.MATCODE, ... etc
FROM tmp_parms tp,
(
SELECT A.COMP_CODE,A.MATCODE, ... etc
Or if you'd prefer yet another inline view:
SELECT C.COMP_CODE,C.MATCODE, ... etc
FROM (
SELECT ? as fr_dt, ? as to_dt, ? as p_comp_code,
? as fr_cat, ? as to_cat, ? as p_sub_code
FROM dual
) tp,
(
SELECT A.COMP_CODE,A.MATCODE, ... etc
And then replace all the existing bind variables with references to the equivalent column from the temporary parms table, i.e. change this:
b.grn_date<=:TO_DT)
to this:
b.grn_date<=tp.to_dt)
So I have this section of my proc:
SELECT
com_contact.rc_name_full as CreatedBy,
capComponent.cm_strike as CapStrike,
floorComponent.cm_strike as FloorStrike,
tq_nominal_notional as Notional,
maxComponent.cm_effective_dt as EffectiveDate,
maxComponent.cm_maturity_dt as MaturityDate,
CAST(CAST(DATEDIFF(mm,maxComponent.cm_effective_dt,maxComponent.cm_maturity_dt) as decimal(9,2))/12 as decimal(9,2)) as term,
(
CASE WHEN se_amort_term_mnth IS NOT NULL THEN se_amort_term_mnth / 12
ELSE CAST(CAST(DATEDIFF(mm,
ISNULL(cmam_amortization_start_dt, maxComponent.cm_effective_dt),
cmam_amortization_end_dt) as decimal(9,2))/12 as decimal(9,2))
END
) AS AmortTermYears,
tq_dd_product as Product,
dh_key_rate as KeyRate,
dh_pv01 as PV01,
dh_val_time_stamp as RateTimeStamp,
re_bnk_le.re_company_name as Company,
rc_contact_id as UserId,
stp_name as NickName,
'' as project,
'' as Borrower,
'' as Lender,
'' as AdditionalInfo,
CASE WHEN tpm_pd_permission_id = 85 THEN 'LLH' WHEN tpm_pd_permission_id = 86 THEN 'ALM' ELSE '' END as Permission,
tr_transaction_id as TransactionId,
NULL as IndicationId
FROM cfo_transaction
The line that says '' as project, we have to actually change to return data now.
The table that next to the FROM, called cfo_transaction has an id on it called tr_transaction_id. We have another table called com_project_transaction_link, that links those id's with project id's, using two two columns called:
pt_tr_transaction_id and pt_pj_project_id, and then we have a table containing all the projects called com_project that has a pj_project_id and a pj_project_name.
GOAL: return the pj_project_name from that projects table where it links with the transactions being pulled.
I really don't know how to do this.
Thanks!
Try this:
SELECT
com_contact.rc_name_full as CreatedBy,
capComponent.cm_strike as CapStrike,
floorComponent.cm_strike as FloorStrike,
tq_nominal_notional as Notional,
maxComponent.cm_effective_dt as EffectiveDate,
maxComponent.cm_maturity_dt as MaturityDate,
CAST(CAST(DATEDIFF(mm,maxComponent.cm_effective_dt,maxComponent.cm_maturity_dt) as decimal(9,2))/12 as decimal(9,2)) as term,
(
CASE WHEN se_amort_term_mnth IS NOT NULL THEN se_amort_term_mnth / 12
ELSE CAST(CAST(DATEDIFF(mm,
ISNULL(cmam_amortization_start_dt, maxComponent.cm_effective_dt),
cmam_amortization_end_dt) as decimal(9,2))/12 as decimal(9,2))
END
) AS AmortTermYears,
tq_dd_product as Product,
dh_key_rate as KeyRate,
dh_pv01 as PV01,
dh_val_time_stamp as RateTimeStamp,
re_bnk_le.re_company_name as Company,
rc_contact_id as UserId,
stp_name as NickName,
PR.pj_project_name as project,
'' as Borrower,
'' as Lender,
'' as AdditionalInfo,
CASE WHEN tpm_pd_permission_id = 85 THEN 'LLH' WHEN tpm_pd_permission_id = 86 THEN 'ALM' ELSE '' END as Permission,
tr_transaction_id as TransactionId,
NULL as IndicationId
FROM cfo_transaction TR
INNER JOIN com_project_transaction_link TL
ON TR.tr_transaction_id = TL.pt_tr_transaction_id
INNER JOIN com_project PR
ON TL.pt_pj_project_id = PR.pj_project_id
The query above assumes that every transaction and project is on the table that joins your tables of projects and transactions (thus the INNER JOIN), but yo can change those to LEFT JOIN if you want
You just add a second join to the other table to the query.
select
yourfields,
p.pj_project_name as project
FROM cfo_transaction t
join com_project_transaction_link tl
on t.tr_transaction_id = tl.pt_tr_transaction_id
join com_project p
on tl.pt_pj_project_id = p.pj_project_id
SELECT ..., cp.pj_project_name
FROM cfo_transaction ct
INNER JOIN com_project_transaction_link cptl
ON ct.tr_transaction_id = cptl.pt_tr_transaction_id
INNER JOIN com_project cp
ON cptl.pt_pj_project_id = cp.pj_project_id
I am creating a script that for "merging" and deleting duplicate rows from a table. The table contains address information, and uses an integer field for storing information about the email as bit flags (column name lngValue). For example, lngValue & 1 == 1 means its the primary address.
There are instances of the same email being entered twice, but sometimes with different lngValues. To resolve this, I need to take the lngValue from all duplicates and assign them to one surviving record and delete the rest.
My biggest headache so far as been with the "merging" of the records. What I want to do is bitwise or all lngValues of duplicate records together. Here is what I have so far, which only finds the value of all lngValues bitwise or'ed together.
Warning: messy code ahead
declare #duplicates table
(
lngInternetPK int,
lngContactFK int,
lngValue int
)
insert into #duplicates (lngInternetPK, lngContactFK, lngValue)
(
select tblminternet.lngInternetPK, tblminternet.lngContactFK, tblminternet.lngValue from tblminternet inner join
(select strAddress, lngcontactfk, count(*) as count from tblminternet where lngValue & 256 <> 256 group by strAddress, lngcontactfk) secondemail
On tblminternet.strAddress = secondemail.strAddress and
tblminternet.lngcontactfk = secondemail.lngcontactfk
where count > 1 and tblminternet.strAddress is not null and tblminternet.lngValue & 256 <> 256 --order by lngContactFK, strAddress
)
update #duplicates set lngValue = t.val
from
(select (sum(dupes.lngValue) & 65535) as val from
(select here.lngInternetPK, here.lngContactFK, here.lngValue from tblminternet here inner join
(select strAddress, lngcontactfk, count(*) as count from tblminternet where lngValue & 256 <> 256 group by strAddress, lngcontactfk) secondemail
On here.strAddress = secondemail.strAddress and
here.lngcontactfk = secondemail.lngcontactfk
where count > 1 and here.strAddress is not null and here.lngValue & 256 <> 256) dupes, tblminternet this
where this.lngContactFK = dupes.lngContactFK
) t
where lngInternetPK in (select lngInternetPK from #duplicates)
Edit:
As requested here is some sample data:
Table Name: tblminternet
Column Names:
lngInternetPK
lngContactFK
lngValue
strAddress
Example row 1:
lngInternetPK: 1
lngContactFK: 1
lngValue: 33
strAddress: "me#myaddress.com"
Example row 2:
lngInternetPK: 2
lngContactFK: 1
lngValue: 40
strAddress: "me#myaddress.com"
If these two were merged here is the desired result:
lngInternetPK: 1
lngContactFK: 1
lngValue: 41
strAddress: "me#myaddress.com"
Other necessary rules:
Each contact can have multiple emails, but each email row must be distinct ( each email can only appear as one row).
SQL Server lacks native bitwise aggregates, that's why we need to emulate them.
The main idea here is to generate a set of bits from 0 to 15, for each bit apply the bitmask to the value and select MAX (which will give us an OR for a given bit), then select the SUM (which will merge the bit masks).
The we just update the first lngInternetPK for any given (lngContactFK, strValue) with the new value of lngValue, and delete all duplicates.
;WITH bits AS
(
SELECT 0 AS b
UNION ALL
SELECT b + 1
FROM bits
WHERE b < 15
),
v AS
(
SELECT i.*,
(
SELECT SUM(value)
FROM (
SELECT MAX(lngValue & POWER(2, b)) AS value
FROM tblmInternet ii
CROSS JOIN
bits
WHERE ii.lngContactFK = i.lngContactFK
AND ii.strAddress = i.strAddress
GROUP BY
b
) q
) AS lngNewValue
FROM (
SELECT ii.*, ROW_NUMBER() OVER (PARTITION BY lngContactFK, strAddress ORDER BY lngInternetPK) AS rn
FROM tblmInternet ii
) i
WHERE rn = 1
)
UPDATE v
SET lngValue = lngNewValue;
;WITH v AS
(
SELECT ii.*, ROW_NUMBER() OVER (PARTITION BY lngContactFK, strAddress ORDER BY lngInternetPK) AS rn
FROM tblmInternet ii
)
DELETE v
WHERE rn > 1
See this article in my blog for more detailed explanations:
SQL Server: aggregate bitwise OR
I believe the following query gets you what you want. This routine assumes a max of two duplicate addresses per contact. If there's more than one dup per contact, the query will have to be modified. I hope this helps.
Declare #tblminternet
Table
( lngInternetPK int,
lngContactFK int,
lngValue int,
strAddress varchar(255)
)
Insert Into #tblminternet
select 1, 1, 33, 'me#myaddress.com'
union
select 2, 1, 40, 'me#myaddress.com'
union
select 3, 2, 33, 'me#myaddress2.com'
union
select 4, 2, 40, 'me#myaddress2.com'
union
select 5, 3, 2, 'me#myaddress3.com'
--Select * from #tblminternet
Select Distinct
A.lngContactFK ,
A.lngValue | B.lngValue as 'Bitwise OR',
A.strAddress
From #tblminternet A, #tblminternet B
Where A.lngContactFK = B.lngContactFK
And A.strAddress = B.strAddress
And A.lngInternetPK != B.lngInternetPK
You can create SQL Server Aggregate functions in .NET that you can then implement in SQL server inline. I think this requires a minimum of SQL server 2005 and Visual Studio 2010. I did one using Visual Studio 2013 Community Edition (free even for commercial use) for use with .NET 2 and SQL Server 2005.
See the MSDN article: https://msdn.microsoft.com/en-us/library/91e6taax(v=vs.90).aspx
First you'll need to enable the CLR feature in SQL server: https://msdn.microsoft.com/en-us/library/ms131048.aspx
sp_configure 'show advanced options', 1;
GO
RECONFIGURE;
GO
sp_configure 'clr enabled', 1;
GO
RECONFIGURE;
GO
Create a SQL Server -> SQL Server Database Project
Right-click on the new project and select Properties
Configure the targeted SQL Server version under Project Settings
Configure the targeted CLR language under SQL CLR (such as VB)
Right-click on the new project and select Add -> New Item...
When the dialog pops up, select SQL Server -> SQL CLR VB -> SQL CLR VB Aggregate
Now you can write your bitwise code in VB:
Imports System
Imports System.Data
Imports System.Data.SqlClient
Imports System.Data.SqlTypes
Imports Microsoft.SqlServer.Server
<Serializable()> _
<Microsoft.SqlServer.Server.SqlUserDefinedAggregate(Format.Native)> _
Public Structure AggregateBitwiseOR
Private CurrentAggregate As SqlTypes.SqlInt32
Public Sub Init()
CurrentAggregate = 0
End Sub
Public Sub Accumulate(ByVal value As SqlTypes.SqlInt32)
'Perform Bitwise OR against aggregate memory
CurrentAggregate = CurrentAggregate OR value
End Sub
Public Sub Merge(ByVal value as AggregateBitwiseOR)
Accumulate(value.Terminate())
End Sub
Public Function Terminate() As SqlInt32
Return CurrentAggregate
End Function
End Structure
Now deploy it: https://msdn.microsoft.com/en-us/library/dahcx0ww(v=vs.90).aspx
Build the project using the menu bar: Build -> Build ProjectName (if the build fails with error 04018 then download a new version of the data tools # http://msdn.microsoft.com/en-US/data/hh297027 or by going to the menu bar: Tools -> Extensions And Updates, then under updates select update for Microsoft SQL Server Update For Database Tooling)
Copy your compiled DLL to C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\Binn and to C:\
Register the DLL:
CREATE ASSEMBLY [CLRTools] FROM ‘c:CLRTools.dll’ WITH PERMISSION_SET = SAFE
Create the aggregate in SQL:
CREATE AGGREGATE [dbo].[AggregateBitwiseOR](#value INT)
RETURNS INT
EXTERNAL NAME [CLRTools].[CLRTools.AggregateBitwiseOR];
If you get the error "Incorrect syntax near 'EXTERNAL'" then change the database compatibility level using following commands:
For SQL Server 2005: EXEC sp_dbcmptlevel 'DatabaseName', 90
For SQL Server 2008: EXEC sp_dbcmptlevel 'DatabaseName', 100
Test your code:
SELECT dbo.AggregateBitwiseOR(Foo) AS Foo FROM Bar
I found this article helpful: http://www.codeproject.com/Articles/37377/SQL-Server-CLR-Functions