Member 14560926 Ответов: 2

Передать запрос параметра в DAL и получить возвращенный набор данных?


ниже приведен код, лежащий в основе формы aspx, где я пытался использовать DAL для получения набора данных обратно.
protected void Page_Load(object sender, EventArgs e)
        {
            data.strConnStr = strConnStr;
            data.openDB();

            strCmd = "SELECT * FROM tblMembers WHERE memNo = @memNo";
            List<SqlParameter> parameters = new List<SqlParameter>();
            SqlCommand cmd = new SqlCommand(strCmd);


            SqlParameter param1 = new SqlParameter();
            param1.ParameterName = "@memNo";
            param1.Value = 63;

            cmd.Parameters.Add(param1);
        
            ds = data.ReturnDataSet(strCmd);
            BindingSource bSource = new BindingSource();
            bSource.DataSource = ds.Tables[0];


Код DAL выглядит следующим образом

using System.Data.Sql;
using System.Data;
using System.Configuration;
using System.Windows;
using System.Data.SqlClient;
using System;
using System.Windows.Forms;


namespace OJT.DAL
{
    public class OJT_Data
    {
        public SqlConnection sQLConnection = new SqlConnection();
        public SqlCommand aCommand = new SqlCommand();
        private string DatabaseName = "";
        public string strConnStr;
        private string strDatabaseName = "";

        public void openDB()
        {
            sQLConnection.ConnectionString = strConnStr;
            sQLConnection.Close();
            sQLConnection.Open();
            aCommand = sQLConnection.CreateCommand();
        }
        public SqlDataReader ReturnData(string SQLDBCommand)
        {
            SqlDataReader r = null;
            try
            {
                aCommand.CommandText = SQLDBCommand;
                r = aCommand.ExecuteReader(System.Data.CommandBehavior.Default);
            }
            catch (SqlException ex)
            {
                MessageBox.Show(ex.Message);
            }
            return r;
        }
        public bool CheckTableExists(string strTableName)
        {
            bool tableExists = false;
            DataTable dt = sQLConnection.GetSchema("tables");
            foreach (DataRow row in dt.Rows)
            {
                string strTbleName = row["TABLE_NAME"].ToString();
                if (row["TABLE_NAME"].ToString() == strTableName)
                {
                    tableExists = true;
                    break;
                }
            }
            return tableExists;
        }
        public DataSet ReturnDataSet(string SQLSelectCommand)
        {
            SqlDataAdapter daGeneric = new SqlDataAdapter(SQLSelectCommand, this.sQLConnection);
            DataSet ds = new DataSet();
            daGeneric.Fill(ds);
            return ds;
        }


        public bool UpdateData(string OdbcCommand)
        {
            bool ret = false;
            try
            {
                aCommand.CommandType = CommandType.Text;
                aCommand.CommandText = OdbcCommand;
                int i = aCommand.ExecuteNonQuery();
                if (i > 0)
                    ret = true;
            }
            catch (SqlException ex)
            {
                MessageBox.Show(ex.Message);
                ret = false;
            }
            finally
            {
                //               conn.Close();
            }
            return ret;
        }
        
    }
}


Что я уже пробовал:

Я уже около недели пытаюсь заставить его работать, но постоянно получаю
System.Data.SqlClient.SqlException: 'Must declare the scalar variable "@memNo".'

в
public DataSet ReturnDataSet(string SQLSelectCommand)
около
daGeneric.Fill(ds);


Некоторая помощь в этом для довольно новичка в этом действительно помогла бы

Richard Deeming

NB: Вы сказали, что это форма ASPX, а это значит, что она ASP.NET, но вы использовали MessageBox.Show в ваших обработчиках исключений.

Ваш код выполняется на сервере. В лучшем случае он выйдет из строя с исключением, сообщающим вам, что вы не можете отобразить окно сообщения из неинтерактивного кода. В худшем случае он отобразит окно сообщения на сервере, где его никто никогда не увидит, и ваш код будет висеть в ожидании администратора, который войдет на сервер и подтвердит тысячи окон сообщений.

Может быть появиться для работы при отладке кода в Visual Studio. Но это только потому, что в данной конкретной ситуации сервер и клиент-это один и тот же компьютер. Как только вы развернете его на реальном сервере, произойдут ужасные вещи.

2 Ответов

Рейтинг:
4

Salman622

Сделайте в соответствии с нижеприведенным предложением:

На этих ниже линии передается строковая переменная, где @памяти не определить

ds = data.ReturnDataSet(strCmd);


измените эту строку, чтобы:
ds = data.ReturnDataSet(cmd);


а затем измените тип параметра на
ReturnDataSet(string SQLSelectCommand)
как указано ниже
public DataSet ReturnDataSet(SqlCommand SQLSelectCommand)


Рейтинг:
17

MadMyche

Проблема, с которой вы столкнулись, похоже, заключается в том, что при построении полной команды SQL вы передаете только текст команды в DAL, а не фактический объект команды

Обычно я делаю так, чтобы DAL был немного более отделен от своих пользователей и передавал запрос, имя параметра и значение. Если существует несколько значений, я передам список пар ключ-значение (строка, объект).

public DataSet ReturnDataSet(string SQLSelectCommand, string ParamName="", object ParamValue)
{
	SqlCommand cmd = new SqlCommand(SQLSelectCommand, this.sQLConnection);
	if (ParamName != "") 
	{
		cmd.Parameters.AddWithValue(ParamName, ParamValue);
	}	

	SqlDataAdapter daGeneric = new SqlDataAdapter(cmd);
	
	// continue on with your code
}


Member 14560926

Спасибо за это, но я все еще получаю ошибку: "необязательный параметр должен появиться после всех необходимых параметров" с скобкой в конце первой строки..."public DataSet ReturnDataSet(string SQLSelectCommand, string ParamName="", object ParamValue)" Есть только один параметр.

MadMyche

Ой... так и должно быть object ParamValue = null

Member 14560926

Бинго, большое спасибо Allgood с одним параметром, но я подозреваю, что могу отправить список так или иначе, мне пришлось позвонить
"ds = данные.ReturnDataSet(strCmd,param1.ParameterName,param1.Value); " чтобы заставить его работать, не уверен в этом, но теперь у меня это работает, отлично....

MadMyche

На самом деле вы могли бы передать имя/значение непосредственно в него - вам не нужна большая часть накладных расходов в вызывающем абоненте

protected void Page_Load(object sender, EventArgs e)
{
	data.strConnStr = strConnStr;
	data.openDB();

	strCmd = "SELECT * FROM tblMembers WHERE memNo = @memNo";
	ds = data.ReturnDataSet(strCmd, "@memNo", 63);
	BindingSource bSource = new BindingSource();
	bSource.DataSource = ds.Tables[0];
}