使用MFC ODBC使用者操作sql2005的存储过程提示这个错误,但是存储过程却执行成功了,我也查过了序列啊,顺序和存储过程的一样啊,这个是怎么回事?
代码如下
CMTmodifyTeacher.cpp文件
#include "stdafx.h"
#include "MTmodifyTeacher.h"
IMPLEMENT_DYNAMIC(CMTmodifyTeacher, CRecordset)CMTmodifyTeacher::CMTmodifyTeacher(CDatabase* pdb)
: CRecordset(pdb)
{
m_lResultValue = 0; m_TNO = "";
m_TNAME = "";
m_TBIRTH = "";
m_TSEX = "";
m_TPHONE = "";
m_TPOST = "";
m_TCOURSE = "";
m_TDEPART = "";
m_TFACE = ""; m_TOLDNO = ""; m_nParams = 11; m_nFields = 0;
m_nDefaultType = dynaset;
}
//#error Security Issue: The connection string may contain a password
// 此连接字符串中可能包含明文密码和/或其他重要
// 信息。请在查看完此连接字符串并找到所有与安全
// 有关的问题后移除 #error。可能需要将此密码存
// 储为其他格式或使用其他的用户身份验证。
CString CMTmodifyTeacher::GetDefaultConnect()
{
return _T("DSN=endscp;uid=sa;pwd=;");
}CString CMTmodifyTeacher::GetDefaultSQL()
{
return _T("{?=call modify_teacher(?,?,?,?,?,\
  ?,?,?,?,?)}");
}void CMTmodifyTeacher::DoFieldExchange(CFieldExchange* pFX)
{
pFX->SetFieldType(CFieldExchange::outputParam);
// RFX_Text() 和 RFX_Int() 这类宏依赖的是
// 成员变量的类型,而不是数据库字段的类型。
// ODBC 尝试自动将列值转换为所请求的类型
RFX_Long(pFX, _T("[@return_value]"), m_lResultValue);
pFX->SetFieldType(CFieldExchange::inputParam); RFX_Text(pFX, _T("[TNO]"), m_TNO);
RFX_Text(pFX, _T("[TNAME]"), m_TNAME);
RFX_Text(pFX, _T("[TBIRTH]"), m_TBIRTH);
RFX_Text(pFX, _T("[TSEX]"), m_TSEX);
RFX_Text(pFX, _T("[TPHONE]"), m_TPHONE);
RFX_Text(pFX, _T("[TPOST]"), m_TPOST);
RFX_Text(pFX, _T("[TCOURSE]"), m_TCOURSE);
RFX_Text(pFX, _T("[TDEPART]"), m_TDEPART);
RFX_Text(pFX, _T("[TFACE]"), m_TFACE); RFX_Text(pFX, _T("[@toldnum]"), m_TOLDNO);}CMTmodifyTeacher.h文件
#pragma once// 代码生成在 2013年4月17日, 1:52class CMTmodifyTeacher : public CRecordset
{
public:
CMTmodifyTeacher(CDatabase* pDatabase = NULL);
DECLARE_DYNAMIC(CMTmodifyTeacher)// 字段/参数数据// 以下字符串类型(如果存在)反映数据库字段(ANSI 数据类型的 CStringA 和 Unicode
// 数据类型的 CStringW)的实际数据类型。
//  这是为防止 ODBC 驱动程序执行可能
// 不必要的转换。如果希望,可以将这些成员更改为
// CString 类型,ODBC 驱动程序将执行所有必要的转换。
// (注意: 必须使用 3.5 版或更高版本的 ODBC 驱动程序
// 以同时支持 Unicode 和这些转换)。 long m_lResultValue; CStringA m_TNO;
CStringA m_TNAME;
CStringA m_TBIRTH;
CStringA m_TSEX;
CStringA m_TPHONE;
CStringA m_TPOST;
CStringA m_TCOURSE;
CStringA m_TDEPART;
CStringA m_TFACE; CStringA    m_TOLDNO;// 重写
// 向导生成的虚函数重写
public:
virtual CString GetDefaultConnect(); // 默认连接字符串 virtual CString GetDefaultSQL();  // 记录集的默认 SQL
virtual void DoFieldExchange(CFieldExchange* pFX); // RFX 支持// 实现
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif};存储过程如下set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
go
-- =============================================
--Created by wln,2013/04/10
-- =============================================
ALTER PROCEDURE [dbo].[modify_teacher]
(
@teachernum [varchar](15),
@teachername [varchar](50),
@teacherbirth [varchar](50),
@teachersex [varchar](5),
@teacherphone [varchar](12),
@teacherpost [varchar](20),
@teachercourse [varchar](20),
@teacherdepart [varchar](20),
@teacherface [varchar](20), @teacheroldnum [varchar](15)
)
AS BEGIN
UPDATE [TEACHER]
SET
[TNO] = @teachernum,
[TNAME] = @teachername,
[TBIRTH] = @teacherbirth,
[TSEX] = @teachersex,
[TPHONE] = @teacherphone,
[TPOST] = @teacherpost,
[TCOURSE] = @teachercourse,
[TDEPART] = @teacherdepart,
[TFACE] = @teacherface
WHERE
[TNO]= @teacheroldnum
END
然后是函数int CDataCenter::ModifyTeacher(TEAINFO& tea, CString oldnum)
{
CMTmodifyTeacher stMod; stMod.m_TNO = tea.teaNo;
stMod.m_TNAME = tea.teaName;
stMod.m_TBIRTH = tea.teaBirth;
stMod.m_TSEX = tea.teaSex;
stMod.m_TPHONE = tea.teaPhone;
stMod.m_TDEPART = tea.teaDepart;
stMod.m_TPOST = tea.teaPost;
stMod.m_TFACE = tea.teaFace;
stMod.m_TCOURSE = tea.teaCourse; stMod.m_TOLDNO = oldnum; stMod.Open();
stMod.Close();
return 0;
}这个是修改按钮的代码void CTeacherAdd::OnBnClickedButtonModify()
{
// TODO: 在此添加控件通知处理程序代码
TEAINFO teacher;
UpdateData(); teacher.teaNo = m_strTeaNum;
teacher.teaName = m_strTeaName; //得到combo_box的文本
int isel = m_comboTeaSex.GetCurSel();
m_comboTeaSex.GetLBText(isel, teacher.teaSex); teacher.teaPhone = m_strTeaPhone; isel = m_comboTeaDepart.GetCurSel();
m_comboTeaDepart.GetLBText(isel, teacher.teaDepart); isel = m_comboTeaPosition.GetCurSel();
m_comboTeaPosition.GetLBText(isel, teacher.teaPost); isel = m_comboTeaFace.GetCurSel();
m_comboTeaFace.GetLBText(isel, teacher.teaFace); isel = m_comboTeaFace.GetCurSel();
m_comboTeaYear.GetLBText(isel, teacher.teaBirth); teacher.teaCourse = m_strCourse; m_DataCenter.ModifyTeacher(teacher, m_strOldNo);
}

解决方案 »

  1.   

    跟不到啊,最后显示汇编了,但是过程中lpszSQL这个指针为空,这是什么原因呢?
      

  2.   


    不行啊,我都查过了,参数都是正确的// MTmodifyTeacher.h : CMTmodifyTeacher 的声明#pragma once// 代码生成在 2013年4月17日, 1:52class CMTmodifyTeacher : public CRecordset
    {
    public:
    CMTmodifyTeacher(CDatabase* pDatabase = NULL);
    DECLARE_DYNAMIC(CMTmodifyTeacher)// 字段/参数数据// 以下字符串类型(如果存在)反映数据库字段(ANSI 数据类型的 CStringA 和 Unicode
    // 数据类型的 CStringW)的实际数据类型。
    //  这是为防止 ODBC 驱动程序执行可能
    // 不必要的转换。如果希望,可以将这些成员更改为
    // CString 类型,ODBC 驱动程序将执行所有必要的转换。
    // (注意: 必须使用 3.5 版或更高版本的 ODBC 驱动程序
    // 以同时支持 Unicode 和这些转换)。 long m_lResultValue; CStringA m_TNO;
    CStringA m_TNAME;
    CStringA m_TBIRTH;
    CStringA m_TSEX;
    CStringA m_TPHONE;
    CStringA m_TPOST;
    CStringA m_TCOURSE;
    CStringA m_TDEPART;
    CStringA m_TFACE; CStringA    m_TOLDNO;// 重写
    // 向导生成的虚函数重写
    public:
    virtual CString GetDefaultConnect(); // 默认连接字符串 virtual CString GetDefaultSQL();  // 记录集的默认 SQL
    virtual void DoFieldExchange(CFieldExchange* pFX); // RFX 支持// 实现
    #ifdef _DEBUG
    virtual void AssertValid() const;
    virtual void Dump(CDumpContext& dc) const;
    #endif};
    这里long m_lResultValue是自己定义的参数,其他的是TEACHER表里的
    而我这里的参数绑定都合适的啊// MTmodifyTeacher.h : CMTmodifyTeacher 类的实现// CMTmodifyTeacher 实现// 代码生成在 2013年4月17日, 1:52#include "stdafx.h"
    #include "MTmodifyTeacher.h"
    IMPLEMENT_DYNAMIC(CMTmodifyTeacher, CRecordset)CMTmodifyTeacher::CMTmodifyTeacher(CDatabase* pdb)
    : CRecordset(pdb)
    {
    m_lResultValue = 0; m_TNO = "";
    m_TNAME = "";
    m_TBIRTH = "";
    m_TSEX = "";
    m_TPHONE = "";
    m_TPOST = "";
    m_TCOURSE = "";
    m_TDEPART = "";
    m_TFACE = ""; m_TOLDNO = ""; m_nParams = 11; m_nFields = 0;
    m_nDefaultType = dynaset;
    }
    //#error Security Issue: The connection string may contain a password
    // 此连接字符串中可能包含明文密码和/或其他重要
    // 信息。请在查看完此连接字符串并找到所有与安全
    // 有关的问题后移除 #error。可能需要将此密码存
    // 储为其他格式或使用其他的用户身份验证。
    CString CMTmodifyTeacher::GetDefaultConnect()
    {
    return _T("DSN=endscp;uid=sa;pwd=;");
    }CString CMTmodifyTeacher::GetDefaultSQL()
    {
    return _T("{?=call modify_teacher(?,?,?,?,?,\
      ?,?,?,?,?)}");
    }void CMTmodifyTeacher::DoFieldExchange(CFieldExchange* pFX)
    {
    pFX->SetFieldType(CFieldExchange::outputParam);
    // RFX_Text() 和 RFX_Int() 这类宏依赖的是
    // 成员变量的类型,而不是数据库字段的类型。
    // ODBC 尝试自动将列值转换为所请求的类型
    RFX_Long(pFX, _T("[@return_value]"), m_lResultValue);
    pFX->SetFieldType(CFieldExchange::inputParam); RFX_Text(pFX, _T("[TNO]"), m_TNO);
    RFX_Text(pFX, _T("[TNAME]"), m_TNAME);
    RFX_Text(pFX, _T("[TBIRTH]"), m_TBIRTH);
    RFX_Text(pFX, _T("[TSEX]"), m_TSEX);
    RFX_Text(pFX, _T("[TPHONE]"), m_TPHONE);
    RFX_Text(pFX, _T("[TPOST]"), m_TPOST);
    RFX_Text(pFX, _T("[TCOURSE]"), m_TCOURSE);
    RFX_Text(pFX, _T("[TDEPART]"), m_TDEPART);
    RFX_Text(pFX, _T("[TFACE]"), m_TFACE); RFX_Text(pFX, _T("[@toldnum]"), m_TOLDNO);}
    /////////////////////////////////////////////////////////////////////////////
    // CMTmodifyTeacher 诊断#ifdef _DEBUG
    void CMTmodifyTeacher::AssertValid() const
    {
    CRecordset::AssertValid();
    }void CMTmodifyTeacher::Dump(CDumpContext& dc) const
    {
    CRecordset::Dump(dc);
    }
    #endif //_DEBUG
    整个过程执行成功了,数据也修改成功了,但是就是弹出那个错误,不知道为什么啊