*Untuk membuat treeview dari 'kategori' yang memiliki 2000 record pada tabel, adalah sebuah ide yg buruk apabila selalu mengambil data dari database. Masalah yang kedua adalah si developer make php, jadi saya hanya batasi bantuan saya di trigger di SQL Servernya saja. Bermaksud untuk ningkatin kinerja, saya membangun html, dan mengupdate jikka ada perubahan terjadi. html ini akan disimpan di tabel juga sih.*
Saya putuskan untuk membuat stored procedure pake C#. yaitu dengan memanfaatkan fitur CLR Integration yang ada di SQL Server 2005. Saya baca dokumen ini karena mau tahu lebih lengkap.
pertama, saya enable CLR integration di SQL Server 2005.
Kedua, saya tulis sebuah stored procedure pake C#.
using
System;
using
System.Data;
using
System.Data.SqlClient;
using
System.Data.SqlTypes;
using
Microsoft.SqlServer.Server;
using
System.Collections;
public
partial
class
StoredProcedures
{
[Microsoft.SqlServer.Server.SqlProcedure]
public
static void
Category_BuildTreeView()
{
string
tree = string.Empty;
tree =
Ul(0);
//
clear html tree
using
(SqlConnection
connection = new
SqlConnection("context
connection=true"))
{
//
get category name
connection.Open();
SqlCommand
command = new
SqlCommand("DELETE
FROM category_tree",
connection);
command.ExecuteNonQuery();
connection.Close();
}
int
part = 1;
using
(SqlConnection
connection = new
SqlConnection("context
connection=true"))
{
//
get category name
connection.Open();
SqlCommand
command = new
SqlCommand("INSERT
INTO category_tree (part,tree) VALUES(@part,@tree)",
connection);
command.Parameters.Add("@part",
SqlDbType.Int);
command.Parameters.Add("@tree",
SqlDbType.NVarChar,
1001);
while
(tree.Length > 1000)
{
string
partstring = tree.Substring(0, 1000);
command.Parameters["@part"].Value
= part;
command.Parameters["@tree"].Value
= partstring;
command.ExecuteNonQuery();
//
cut a tree
tree = tree.Substring(1000);
part++;
}
//
the last one.
command.Parameters["@part"].Value
= part;
command.Parameters["@tree"].Value
= tree;
command.ExecuteNonQuery();
connection.Close();
}
}
public
static
string
Li(int
categoryId)
{
//
return empty if invalid
if
(categoryId == 0)
{
return
string.Empty;
}
string
li = "<li>";
int
children = 0;
//
Connect through the context connection.
using
(SqlConnection
connection = new
SqlConnection("context
connection=true"))
{
//
get category name
connection.Open();
SqlCommand
command = new
SqlCommand("SELECT
* FROM category WHERE ID="
+ categoryId.ToString(), connection);
SqlDataReader
reader = command.ExecuteReader();
if
(reader.Read())
{
li
+= "<a href=\"Default.aspx?cat=" +
categoryId + "\" >"
+ reader["category_name"].ToString()
+ "("
+ reader["count_items"].ToString()
+ ")</a>";
children
= int.Parse(reader["count_child"].ToString());
}
reader.Close();
connection.Close();
}
if
(children > 0)
{
li
+= Ul(categoryId);
}
li
+= "</li>";
return
li;
}
private
static
string
Ul(int
categoryId)
{
string
ul = "<ul>";
ArrayList
children = new
ArrayList();
//
Connect through the context connection.
using
(SqlConnection
connection = new
SqlConnection("context
connection=true"))
{
//
get children ids
connection.Open();
SqlCommand
command = new
SqlCommand("SELECT
DISTINCT ID FROM category WHERE category_parent="
+ categoryId.ToString(), connection);
SqlDataReader
reader = command.ExecuteReader();
while
(reader.Read())
{
children.Add(reader["ID"].ToString());
}
reader.Close();
connection.Close();
}
foreach
(string id
in
children)
{
ul
+= Li(id);
}
ul
+= "</ul>";
return
ul;
}
public
static
string
Li(string
categoryId)
{
return
Li(int.Parse(categoryId));
}
};
Ketiga, SAYA GAK MAU BIKIN TRIGGER PAKE CLR INTEGRATION, karena saya memerlukan fitur ini pada bagian yang memerlukan teknik reksursif
tingkat tinggi *ceileeeeh* saja dan supaya bisa 'didaur ulang', tetapi dari trigger saya bisa panggil stored procedure.
Semoga membantu.