PDA

View Full Version : سوال: مشکل در پر کردن DataSet به کمک Procedure



mahdidabaghi
دوشنبه 09 بهمن 1391, 17:55 عصر
سلام به اساتید
من میخوام data Set رو به کمک پروسیجری که تو اس کیو ال نوشتم پر کنم.ولی روند کار رو به این صورت انجام دادم ولی نتیجه ای نگرفتم.
ممنون میشم راهنمایی کنید که کد پایین رو چه تغییری باید بدم؟
کد پر کردن Data Set

System.Data.SqlClient.SqlConnection connection = new System.Data.SqlClient.SqlConnection("Data Source=.;Initial Catalog=portal;Integrated Security=True");
connection.Open();
System.Data.SqlClient.SqlCommand command = new System.Data.SqlClient.SqlCommand();
command.Connection = connection;
command.CommandText = "proc_test";
command.CommandType = CommandType.StoredProcedure;
SqlDataAdapter adapter = new SqlDataAdapter(command);
DataSet dataSet = new DataSet();
adapter.Fill(dataSet);
return dataSet;
پروسیجر :

ALTER Proc [dbo].[proc_test]

As
Select Role_Id As 'شناسه' , Role_Name_Fa As 'عنوان نقش' , Role_Name_En As 'نام نقش' , Role_Date As 'تاريخ ثبت' From tbl_role

malloc
دوشنبه 09 بهمن 1391, 19:38 عصر
تابع و کامل میزاشتی دیگه.

بعد این که return کردی برنامه به کدوم خط میره . یعنی این datalist که برمیگرده کجا قرار میگیره و چطور قرار میگیره ..

فکر میکنم اگه از break point استفاده کنی میتونی بفهمی کجا باعث میشه که جواب نگیری

mahdidabaghi
دوشنبه 09 بهمن 1391, 21:30 عصر
مرسی از پاسختون
شما اصلا فرض کن اون خط اخریه وجود نداره.وقتی break point میذارم و برنامه رو گام بگام اجرا میکنم اونوقت dataset من هیچ سطری برنمیگردونه (has row = false)
مشکل من اینجاشه.مهندس میشه یه نمونه درست کنی که این کار رو به روشی که عرض کردم انجام بده؟
یا کد رو ببینی کجاش ایراد داره؟
پر رویی بنده رو به بزرگی خودتون ببخشید

aslan
دوشنبه 09 بهمن 1391, 22:22 عصر
مرسی از پاسختون
شما اصلا فرض کن اون خط اخریه وجود نداره.وقتی break point میذارم و برنامه رو گام بگام اجرا میکنم اونوقت dataset من هیچ سطری برنمیگردونه (has row = false)
مشکل من اینجاشه.مهندس میشه یه نمونه درست کنی که این کار رو به روشی که عرض کردم انجام بده؟
یا کد رو ببینی کجاش ایراد داره؟
پر رویی بنده رو به بزرگی خودتون ببخشید

سلام
کدتون ظاهرا مشکلی نداره و درسته
برای اطمینان در سطر ماقبل آخر ( قبل از return dataset ) این کد و قرار بدین و تست کنین


int tedad = dataSet.Tables[0].Rows.Count;

mahdidabaghi
چهارشنبه 11 بهمن 1391, 00:26 صبح
سلام مجدد
ابتدا راجع به کد زیر بگم که با این کد میشه گرید رو به صورت ایجکسی رفرش کرد که واسه خودم خیلی جذاب و جالبه.
سمت کلاینت:

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript">
function refresh() {
$(function () {
$.ajax({
type: "POST",
url: "Default.aspx/GetCustomers",
data: '{}',
contentType: "application/json; charset=utf-8",
dataType: "json",
success: OnSuccess,
failure: function (response) {
alert(response.d);
},
error: function (response) {
alert(response.d);
}
});
});
}
function OnSuccess(response) {
var xmlDoc = $.parseXML(response.d);
var xml = $(xmlDoc);
var customers = xml.find("Table");
var row = $("[id*=gvCustomers] tr:last-child").clone(true);
$("[id*=gvCustomers] tr").not($("[id*=gvCustomers] tr:first-child")).remove();
$.each(customers, function () {
var customer = $(this);
$("td", row).eq(0).html($(this).find("Role_Id").text());
$("td", row).eq(1).html($(this).find("Role_Name_Fa").text());
$("td", row).eq(2).html($(this).find("Role_Name_En").text());
$("[id*=gvCustomers]").append(row);
row = $("[id*=gvCustomers] tr:last-child").clone(true);
});
}
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:GridView ID="gvCustomers" runat="server" AutoGenerateColumns="false" Font-Names="Arial"
Font-Size="10pt" RowStyle-BackColor="#A1DCF2" HeaderStyle-BackColor="#3AC0F2"
HeaderStyle-ForeColor="White">
<Columns>
<asp:BoundField ItemStyle-Width="150px" DataField="Role_Id" HeaderText="Role_Id" />
<asp:BoundField ItemStyle-Width="150px" DataField="Role_Name_Fa" HeaderText="Role_Name_Fa" />
<asp:BoundField ItemStyle-Width="150px" DataField="Role_Name_En" HeaderText="Role_Name_En" />
</Columns>
</asp:GridView>
<input id="Button1" type="button" value="button" onclick="refresh()"/>
</div>
</form>
</body>
</html>

سمت سرور :

protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
this.BindDummyRow();
}
}

private void BindDummyRow()
{
DataTable dummy = new DataTable();
dummy.Columns.Add("Role_Id");
dummy.Columns.Add("Role_Name_Fa");
dummy.Columns.Add("Role_Name_En");
dummy.Rows.Add();
gvCustomers.DataSource = dummy;
gvCustomers.DataBind();
}

[WebMethod]
public static string GetCustomers()
{
return GetData().GetXml();
}
private static DataSet GetData()
{
string query = "SELECT Role_Id, Role_Name_Fa, Role_Name_En FROM tbl_role";
SqlCommand cmd = new SqlCommand(query);
string strConnString = ConfigurationManager.ConnectionStrings["portalConnectionString"].ConnectionString;
using (SqlConnection con = new SqlConnection(strConnString))
{
using (SqlDataAdapter sda = new SqlDataAdapter())
{
cmd.Connection = con;
sda.SelectCommand = cmd;
using (DataSet ds = new DataSet())
{
sda.Fill(ds);
return ds;
}
}
}
}

کد بالا عین هلو و بدون اشکال گرید رو رفرش میکنه
ولی حالا میخوام اون Command رو که به صورت دستی نوشتم رو به صورت Procedure دربیارم.یعنی بگم Command عزیز برو واسه اجرای دستور Procedure رو اجرا کن و Dataset رو پر کن و تابع GetData() بالا رو به این صورت تغییر دادم:

private static DataSet GetData()
{

System.Data.SqlClient.SqlConnection connection = new System.Data.SqlClient.SqlConnection("Data Source=.;Initial Catalog=portal;Integrated Security=True");
connection.Open();
System.Data.SqlClient.SqlCommand command = new System.Data.SqlClient.SqlCommand();
command.Connection = connection;
command.CommandText = "Sp_test";
command.CommandType = CommandType.StoredProcedure;
command.ExecuteReader();
SqlDataAdapter adapter = new SqlDataAdapter(command);
DataSet dataSet = new DataSet();
connection.Close();
adapter.Fill(dataSet);
int s = dataSet.Tables[0].Rows.Count;
return dataSet;
}

اما این یکی جواب نمیده و گرید خالی میشه بجای این که رفرش شه.
ممنون میشم راهنمایی کنین این کد اخریه چه اشکالی داره که رفرش صورت نمیگیره

malloc
چهارشنبه 11 بهمن 1391, 02:06 صبح
چرا static تعریف کردی ؟؟؟

معمولا یکی از خطاهای منطقی که میگیره واسه static بودنه . اگه واسه static نوشتن دلیل محکمی داری که هیچی والا یبار بدون static تابع رو اجرا کن

اوبالیت به بو
چهارشنبه 11 بهمن 1391, 09:54 صبح
اشکال کار شما اینجاست:



private static DataSet GetData()
{

System.Data.SqlClient.SqlConnection connection = new System.Data.SqlClient.SqlConnection("Data Source=.;Initial Catalog=portal;Integrated Security=True");
connection.Open();
System.Data.SqlClient.SqlCommand command = new System.Data.SqlClient.SqlCommand();
command.Connection = connection;
command.CommandText = "Sp_test";
command.CommandType = CommandType.StoredProcedure;
command.ExecuteReader();
SqlDataAdapter adapter = new SqlDataAdapter(command);
DataSet dataSet = new DataSet();
connection.Close();
adapter.Fill(dataSet);
int s = dataSet.Tables[0].Rows.Count;
return dataSet;
}




چرا قبل از همه ExecuteReader رو اجرا کردید؟ اصلا چرا نوشتید؟ پاک کنید.
چرا connection.Close رو قبل از fill کردن DataAdapter نوشتید؟

mahdidabaghi
چهارشنبه 11 بهمن 1391, 11:35 صبح
ممنون از پاسختون
حقیقت هر کار که روی کد انجام دادم نشد و بالاخره اون کد پست 5 رو گذاشتم.الانم متاسفانه لپ تاپم همراهم نیس.
امیدوارم با حذف ExecuteReader و گذاشتن Connecion Close بعد از FIill کردن Data Set مشکل حل شه

mahdidabaghi
شنبه 14 بهمن 1391, 12:12 عصر
سلام دوست گرامی
من تغییراتی رو که در پست 8 عرض کرده بودم و انجام دادم ولی متاسفانه جواب نگرفتم.
ممنون میشم راهنمایی مجدد بفرمایید

mahdidabaghi
شنبه 14 بهمن 1391, 18:38 عصر
اساتید کماکان منتظر پاسخ های شما هستم

اوبالیت به بو
شنبه 14 بهمن 1391, 18:42 عصر
اساتید کماکان منتظر پاسخ های شما هستم

کدهاتون رو قرار بدید + چه خطایی به شما می ده؟

mahdidabaghi
شنبه 14 بهمن 1391, 20:31 عصر
دوست عزیز اگر توجه کنید کدها را در پست های بالا قرار داده ام.لطفا توجه کنید.در ضمن متاسفانه با توجه به کدهای فوق،اطلاعات گرید پس از رفرش،ناپدید می شوند ( ااطلاعاتی در گرید نمایش داده نمی شود )

اوبالیت به بو
شنبه 14 بهمن 1391, 21:23 عصر
دوست عزیز اگر توجه کنید کدها را در پست های بالا قرار داده ام.لطفا توجه کنید.در ضمن متاسفانه با توجه به کدهای فوق،اطلاعات گرید پس از رفرش،ناپدید می شوند ( ااطلاعاتی در گرید نمایش داده نمی شود )

من توجه کنم؟!؟؟؟

در پست بالا که همون کدهای قدیم قرار داده شده.
برای مساله رفرش آیا دستور Page.IsPostback رو در Page_Load قرار دادید؟

mahdidabaghi
سه شنبه 17 بهمن 1391, 00:11 صبح
شرمنده اگه دیر جواب میدم
من در اخر پست 5 کدی که از اون جواب نمیگیرم رو گذاشتم و تغییراتی به این صورت رو اعمال کردم:

private static DataSet GetData()
{

System.Data.SqlClient.SqlConnection connection = new System.Data.SqlClient.SqlConnection("Data Source=.;Initial Catalog=portal;Integrated Security=True");

System.Data.SqlClient.SqlCommand command = new System.Data.SqlClient.SqlCommand();
command.Connection = connection;
command.CommandText = "Sp_test";
command.CommandType = CommandType.StoredProcedure;

SqlDataAdapter adapter = new SqlDataAdapter(command);
DataSet dataSet = new DataSet();

adapter.Fill(dataSet);

return dataSet;
}
اما این هم جواب نداد.
لطفا من رو راهنمایی بفرمایید کد بالا را چه تغییری باید بدم تا گرید خالی نشه؟

hdhd1110
سه شنبه 17 بهمن 1391, 00:16 صبح
شما باید برای پر کردن dataset اینطور عمل کنید
[adapter.fill(dataset,"Table

mahdidabaghi
سه شنبه 17 بهمن 1391, 09:20 صبح
سلام دوباره
من طبق گفته شما کد رو به صورت های زیر تغییردادم ولی باز هم نشد

adapter.Fill(dataSet,'Table');


adapter.Fill(dataSet,'Table[0]');

ولی باز هم نتیجه ای نگرفتم
دوستان لطفا راهنمایی کنید گیر کار کجایه اخه؟:گریه:

اوبالیت به بو
سه شنبه 17 بهمن 1391, 11:31 صبح
adapter.Fill(dataSet);

دوست من Connection رو باز نکردی.:



connection.Open();
adapter.Fill(dataSet);
connection.Close();

mahdidabaghi
سه شنبه 17 بهمن 1391, 12:45 عصر
adapter.Fill(dataSet);

دوست من Connection رو باز نکردی.:



connection.Open();
adapter.Fill(dataSet);
connection.Close();


واقعا از پاسخ شما کمال تشکر رو دارم ولی باز هم نتیجه نگرفتم.(با کلیک بر روی دکمه گرید بجای اینکه رفرش شه خالی میشه)
اینهم کدی که با کمک شما به این صورت تغییر دادم:

private static DataSet GetData()
{

System.Data.SqlClient.SqlConnection connection = new System.Data.SqlClient.SqlConnection("Data Source=.;Initial Catalog=portal;Integrated Security=True");

System.Data.SqlClient.SqlCommand command = new System.Data.SqlClient.SqlCommand();
command.Connection = connection;
command.CommandText = "Sp_test";
command.CommandType = CommandType.StoredProcedure;

SqlDataAdapter adapter = new SqlDataAdapter(command);
DataSet dataSet = new DataSet();
connection.Open();
adapter.Fill(dataSet);
connection.Close();


return dataSet;
}

Himalaya
سه شنبه 17 بهمن 1391, 13:57 عصر
سلام


چرا static تعریف کردی ؟؟؟
معمولا یکی از خطاهای منطقی که میگیره واسه static بودنه . اگه واسه static
نوشتن دلیل محکمی داری که هیچی والا یبار بدون static تابع رو اجرا کن
چون واسه استفاده از Ajax از WebMethod استفاده کرده، باید تابع GetCustomers به صورت استاتیک تعریف کنه و چون تابع GetDate هم توسط همین تابع استاتیک
فراخوانی شده، اونم باید استاتیک باشه



دوست من Connection رو باز نکردی
موقع کار کردن با SqlDataAdapter نیازی نیست شما باز و بسته شدن کانکشن رو مدیریت کنید. این کارو بسپارید به همون SqlDataAdapter

اما در مورد مشکل دوستمون
اول اینکه تو پست 1 اسم proc رو گزاشتید proc_test و با همین اسم هم تو کدای پست 1 صداش کردید. اما تو پست آخر با اسم Sp_test صداش کردید. احتمالا محض تست کردن بوده ولی بهش دقت کنید
دوم اینکه شما طبق Procedure پست 1 به ستونها اسم مجازی دادید (اونم فارسی، اصلا کار خوبی نیست). خوب مشخصه که تو نتیجه برگشتی از سمت سرور دیگه شما چیزی به اسم Role_Name_Fa ندارید که حالا قرار باشه با جاوا اسکریپت مقدارش رو بخونید


$(this).find("Role_Name_Fa").text()


با کلیک بر روی دکمه گرید بجای اینکه رفرش شه خالی میشه
دلیلش همون مورد 2 هستش

[WebMethod]
public static string GetCustomers()
{
var connection = new SqlConnection(ConfigurationManager.ConnectionStrin gs["portalConnectionString"].ConnectionString);
var command = new SqlCommand
{
Connection = connection,
CommandText = "proc_test",
CommandType = CommandType.StoredProcedure
};
var adapter = new SqlDataAdapter(command);
var dataSet = new DataSet();
adapter.Fill(dataSet);
return dataSet.GetXml();
}

mahdidabaghi
سه شنبه 17 بهمن 1391, 23:58 عصر
مهندس بابت جوابتون خیلی متشکرم.بالاخره با توضیح بجای شما مشکل من حل شد.یه سه چهار روزی واسه همین قضیه کارم ساکن مونده بود.
فقط یه سوال دیگه

دوم اینکه شما طبق Procedure پست 1 به ستونها اسم مجازی دادید (اونم فارسی، اصلا کار خوبی نیست)
علت این که فرمودین از اسم مجازی اونم از نوع فارسیش استفاده نکنم چیه؟
ممنون میشم این مورد رو هم توضیح بدین
سپاس از شما و البته سایر دوستان دیگه که توی این تایپیک من رو با راهنمایی های خودشون شرمنده کردن

na_des
چهارشنبه 18 بهمن 1391, 00:20 صبح
دوسته عزیز از توضیحات خوبتون سپاسگزارم :لبخندساده:
سلام
چون واسه استفاده از Ajax از WebMethod استفاده کرده، باید تابع GetCustomers به صورت استاتیک تعریف کنه و چون تابع GetDate هم توسط همین تابع استاتیک
فراخوانی شده، اونم باید استاتیک باشه

موقع کار کردن با SqlDataAdapter نیازی نیست شما باز و بسته شدن کانکشن رو مدیریت کنید. این کارو بسپارید به همون SqlDataAdapter

اما در مورد مشکل دوستمون
اول اینکه تو پست 1 اسم proc رو گزاشتید proc_test و با همین اسم هم تو کدای پست 1 صداش کردید. اما تو پست آخر با اسم Sp_test صداش کردید. احتمالا محض تست کردن بوده ولی بهش دقت کنید
دوم اینکه شما طبق Procedure پست 1 به ستونها اسم مجازی دادید (اونم فارسی، اصلا کار خوبی نیست). خوب مشخصه که تو نتیجه برگشتی از سمت سرور دیگه شما چیزی به اسم Role_Name_Fa ندارید که حالا قرار باشه با جاوا اسکریپت مقدارش رو بخونید


$(this).find("Role_Name_Fa").text()
دلیلش همون مورد 2 هستش

[WebMethod]
public static string GetCustomers()
{
var connection = new SqlConnection(ConfigurationManager.ConnectionStrin gs["portalConnectionString"].ConnectionString);
var command = new SqlCommand
{
Connection = connection,
CommandText = "proc_test",
CommandType = CommandType.StoredProcedure
};
var adapter = new SqlDataAdapter(command);
var dataSet = new DataSet();
adapter.Fill(dataSet);
return dataSet.GetXml();
}

Himalaya
چهارشنبه 18 بهمن 1391, 00:50 صبح
سلام

علت این که فرمودین از اسم مجازی اونم از نوع فارسیش استفاده نکنم چیه؟ببینید، مثلا اگه بخوایم در ارتباط با سوال همین تاپیک حرف بزنیم، دستور زیر


select Id,Caption from City
Xml زیر رو تولید میکنه

<?xml version="1.0" encoding="utf-8"?>
<NewDataSet>
<Table>
<Id>8</Id>
<Caption>بندرعباس</Caption>
</Table>
</NewDataSet>و دستور

select Id as [شماره],Caption as [عنوان] from City
Xml زیر رو

<?xml version="1.0" encoding="utf-8"?>
<NewDataSet>
<Table>
<شماره>8</شماره>
<عنوان>بندرعباس</عنوان>
</Table>
</NewDataSet>شما قالب کدوم سند Xml رو بیشتر میپسندید؟ اونی که Node هاش فارسی هست یا اونی که انگلیسی هست.
اصلا چندجا دیدید برنامه نویس بیاد یه سند Xml رو با Node های فارسی ایجاد کنه؟ اگه دیده باشید به برنامه نوس بودن طرف شک کنید. (منظورم شما ایجاد کننده تاپیک نیستید، مورد شما از روی اشتباه بوده نه عمد)

مثل این میمونه که طرف بیاد تو #C متغیر ها رو با اسامی فارسی ایجاد کنید (آدم حتی از تصور اینجور کدا چندشش میشه، چه برسه به اینکه واقعا به چشم ببینه)
یا حتی در مورد GridView تو asp.net یا DataGridView تو ویندوز اپلیکیشن. طرف میاد تو سلکتی که میزنه به همین صورت اسامی مجازی درنظر میگیره (فارسی) و نتیجه رو میده به برنامه. خوب مگه خود گرید بخشی با عنوان HeaderText برای ست کردن هدر ستونها نداره که طرف بخواد با این شیوه عنوان ستون رو فارسی کنه؟

از تعیین اسم مجازی (سمت Sql) بیشتر زمانی استفاده میشه که مثلا شما بخواید یه ستون محاسباتی تو دستور Sql داشته باشید (یا مثلا بخواید از توابع Sum و Count و ...) استفاده کنید و نتیجه اونا رو
با یه اسم معنی دار (واسه ستون) به کاربر نشون بدید (یا بفرستیدش واسه برنامه، البته اونم انگلیسی نه فارسی)

mahdidabaghi
چهارشنبه 18 بهمن 1391, 01:01 صبح
بسیار متشکرم و از گفته های شما لذت بردم
حقیقت من تو زمینه ای اس پی تازه وارد شدم و لذا تجربیات و فرموده هایی دوستانی چون شما میتونه خیلی کار گشا باشه
باز هم شرمنده که سوال دیگه ای برای من مطرح شد.هرچند این سوال رو در یه پست جداگانه هم مطرح کردم ولی ...
ایا این سبک برنامه نویسی (یعنی کار با وب سرویس و جی کوئری و Xml )از لحاظ امنیتی خدشه ای به سایتی که طراحی کردم ایجاد نمیکنه.
در واقع تمام عملیات قسمت مدیریتی سایت از جمله ثبت و ویرایش و حذف و ... به صورت ایجکسی و با کمک Java و JQurery و Json , وب سرویس انجام دادم.

Himalaya
چهارشنبه 18 بهمن 1391, 13:09 عصر
سلام ------


باز هم شرمنده که سوال دیگه ای برای من مطرح شد.هرچند این سوال رو در یه پست جداگانه هم مطرح کردم ولی ...


قانون شماره 8
لطفاً در هنگام طرح سوالات خود آن ها را به صورت جداگانه مطرح فرمایید. بدین معنی که در صورتی که سوال های گوناگونی دارید، آنها را در چندین تاپیک مطرح نمایید و از مطرح کردن تمامی سوالات در یک ارسال خودداری فرمایید.