SqlDataSource SelectCommand, использующий LIKE, не работает - PullRequest
0 голосов
/ 27 марта 2009

У меня есть следующий T-SQL в SelectCommand:

SELECT h.Business,
hrl.frn
FROM registration hrl
INNER JOIN holder h on h.call = hrl.call
WHERE 
(h.Business like '%' + @business + '%' and h.Business is not null) 
and 
(hrl.frn = @frn and hrl.frn is not null)

business и frn связаны с параметрами управления, и он должен возвращать данные, даже если один или оба оставлены пустыми, но если я введу данные только для frn, например, он ничего не возвращает. Я думаю, что мой T-SQL не работает правильно, и я также не уверен, правильно ли я обращаюсь с like.

если оба текстовых поля оставлены пустыми, должны быть возвращены все данные. Если введен frn, но business оставлен пустым, он должен возвращать только данные, относящиеся к этому frn. Если business в случае ввода, но frn оставить пустым, он должен вернуть все совпадения like business. Если оба введены, он должен возвращать только данные, соответствующие frn и business.

Кроме того, я не уверен, действительно ли необходимо делать and is not null.

protected void btnSearch_Click(object sender, EventArgs e)
{
    if (txtFRN.Text == "")
        frn = null;

    if (txtBusiness.Text == "")
        business = null;

    sqlDsMaster.SelectParameters[frn].DefaultValue = frn;
    sqlDsMaster.SelectParameters[business].DefaultValue = business;

    sqlDsMaster.DataBind();
}

Выше выдается «Ссылка на объект, не установленная для экземпляра», когда он попадает в эту строку:

sqlDsMaster.SelectParameters[frn].DefaultValue = frn;

frn и business являются свойствами.


Вот хранимая процедура SearchMaster:

CREAETE PROCEDURE SearchMaster
@business nvarchar(300) = NULL,
@frn nvarchar(10) = NULL
AS
SELECT h.Business,
       hrl.frn
FROM registration hrl
INNER JOIN holder h on h.call = hrl.call
WHERE (@business IS NULL OR h.Business like '%' + @business + '%') 
  AND (@frn IS NULL OR hrl.frn = @frn)

Вот хранимая процедура SearchDetails:

CREATE PROCEDURE SearchDetails
@business nvarchar(300) = NULL,
@frn nvarchar(10) = NULL
AS
SELECT hrl.call 
FROM registration hrl 
INNER JOIN holder h ON h.call = hrl.call
WHERE (@business IS NULL OR h.Business LIKE '%' + @business + '%') 
      AND (@frn IS NULL OR hrl.frn = @frn)

Вот SqlDataSource для процедуры SearchMaster:

<asp:SqlDataSource ID="sqlDsDetails" 
                   runat="server" 
                   ConnectionString="<%$ ConnectionStrings:cnxString %>
                   SelectCommandType="StoredProcedure" 
                   SelectCommand="SearchMaster">
  <SelectParameters>
    <asp:ControlParameter Name="business" ControlID="txtBusiness" 
                          Type="String" PropertyName="Text"  
                          ConvertEmptyStringToNull="true" />
    <asp:ControlParameter Name="frn" ControlID="txtFRN" 
                          Type="String" PropertyName="Text"
                          ConvertEmptyStringToNull="true"/>
  </SelectParameters>
</asp:SqlDataSource>

Вот SqlDataSource для процедуры SearchDetails:

<asp:SqlDataSource ID="sqlDsDetails" 
                   runat="server" 
                   ConnectionString="<%$ ConnectionStrings:cnxString %>
                   SelectCommandType="StoredProcedure" 
                   SelectCommand="SearchDetails">
  <SelectParameters>
    <asp:Parameter Name="frn" Type="String" DefaultValue="" 
                   ConvertEmptyStringToNull="true" />
    <asp:Parameter Name="business" Type="String" DefaultValue="" 
                   ConvertEmptyStringToNull="true" />
  </SelectParameters>
</asp:SqlDataSource>

Вот нажатие кнопки, которая связывает SqlDsMaster:

protected void btnSearch_Click(object sender, EventArgs e)
{
    sqlDsMaster.DataBind();
}

Вот gvMaster_RowCreated, который создает строки для деталей:

protected void gvMaster_RowCreated(object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        SqlDataSource ctrl = 
        e.Row.FindControl("sqlDsDetails") as SqlDataSource;

        if (ctrl != null && e.Row.DataItem != null)
        {
            ctrl.SelectParameters["frn"].DefaultValue = 
            ((DataRowView)e.Row.DataItem)["frn"].ToString();

            ctrl.SelectParameters["business"].DefaultValue = 
            ((DataRowView)e.Row.DataItem)["business"].ToString();
         }
     }
 }

SearchMaster и SearchDetails оба работают, если я запускаю его через SQL Server Management Studio, и это работает, если я ввожу оба данных для business и frn, но если я введу только одно, данные не возвращаются. Параметры настроены правильно? Кроме того, если я инициализирую параметры для null в процедуре, все еще необходимо использовать ConvertEmptyStringToNull?

Ответы [ 3 ]

2 голосов
/ 27 марта 2009

Я бы сделал что-то вроде:

where (@business is null
          or @business = ''
          or h.Business like '%' + @business + '%')
      and (@frn is null
              or @frn = ''
              or hrl.frn = @frn)

Если вы пустили пустые строки поиска до их передачи, вы можете пропустить часть @yyy = ''.

0 голосов
/ 12 мая 2009

"and is not null"

Хранимые процедуры имеют право: (@frn IS NULL OR hrl.frn = @frn). Вы хотите выбрать любую строку, либо если frn равно null, либо совпадает. Тот же шаблон применим к свойству business.

NullReferenceException

sqlDsMaster.SelectParameters[frn].DefaultValue = frn;

Это невозможно, поскольку вы используете значение свойства frn (которое может быть null) вместо строки "frn" в качестве индекса в SelectParameters. У вас та же ошибка в следующей строке с business вместо "business".

ConvertEmptyStringToNull

Я бы поставил вопрос наоборот: если вы используете ConvertEmptyStringToNull, почему вы хотите обременять абонента той же функциональностью? Если только пустая строка не будет действительным значением для frn или business, я бы оставил ConvertEmptyStringToNull установленным и не заботился бы об этом в вызывающей стороне.

Надеюсь, это ответит на все ваши вопросы.

0 голосов
/ 27 марта 2009

Изменение

"и ч.бизнес не нулевой"

до

"или h. Бизнес нулевой"

и

"и hrl.frn не равен нулю"

до

"или hrl.frn is null"

Это вернет все, когда эти параметры будут нулевыми.

...