Makale numarası: 235053 - Son Gözden Geçirme: 03 Kasım 2003 Pazartesi - Gözden geçirme: 2.2

SORUN: E_FAIL SQL deyimi içinde bir alt sorgusu olan bir parametre içerir, Prepare() döndürdü.

Sistem İpucuBu makale, kullandığınızdan farklı bir işletim sistemine yöneliktir. Sizinle ilgili olmayabilecek makale içeriği devre dışı bırakıldı.

Bu Sayfada

Hepsini aç | Hepsini kapa

Belirtiler

SQL Server için OLE DB sağlayıcı kullanarak ve ATL CCommand::Prepare() işlevi veya ICommandPrepare::Prepare(), arama E_FAIL ile aşağıdaki hata açıklamasını verir:
Sözdizimi hatası veya erişim ihlali.
SQL Server OLE DB gelen Provider MDAC 2.7 birlikte aşağıdaki Gelişmiş hata iletisini döndürür:
SQL deyimlerini sub-select sorgularla parametre bilgileri türetilemez. Komutu hazırlamadan önce parametre bilgilerini ayarlayın.

Neden

OLE DB komut nesnesi için SQL komut metni bir alt sorgu parametre içerir. Örneğin, aşağıdaki SQL deyimi hataya neden olur:
SELECT * FROM Table1 WHERE field2 IN <BR/>
(SELECT field1 FROM Table2 where field1 > ?)
				

SQL Server için Microsoft OLE DB sağlayıcısı, alt sorgular parametre bilgileri türetilemez.

Çözüm

Prepare() çağırmadan önce CCommand::SetParameterInfo() veya ICommandWithParameters::SetParameterInfo() çağırmalısınız.

Lütfen, bu makalenin ATL OLE DB tüketici şablonlarını kullanır ve arama SetParameterInfo() gösteren örnek kod için EK BILGILER bölümüne bakın.

Durum

Bu davranış tasarım yüzündendir.

Daha fazla bilgi

Davranışı yeniden oluşturma adımları

  1. Bir Microsoft SQL Server veritabanında iki tablo oluşturun: Table1 bir karakter ve bir tamsayı olmalıdır, Table2 bir tamsayı alanı olmalıdır.
  2. Aşağıdakine benzer bir erişimci sınıfı oluştur:
    class CQuery1Accessor
    {
    public:
    	TCHAR m_field1[11];
    	LONG  m_field2;
    	LONG  m_field1param;
    
    BEGIN_COLUMN_MAP(CQuery1Accessor)
    	COLUMN_ENTRY(1, m_field1)
    	COLUMN_ENTRY(2, m_field2)
    
    END_COLUMN_MAP()
    
    BEGIN_PARAM_MAP(CQuery1Accessor)
    	COLUMN_ENTRY(1,m_field1param)
    END_PARAM_MAP()
    DEFINE_COMMAND(CQuery1Accessor, _T("SELECT * FROM Table1 WHERE field2 IN"
    			   "(SELECT field1 FROM Table2 where field1 > ?)"));
    
    	// You may want to call this function if you are inserting a record and want to
    	// initialize all the fields, if you are not going to explicitly set all of them.
    	void ClearRecord()
    	{
    		memset(this, 0, sizeof(*this));
    	}
    };
    
    						
  3. Yeni oluşturduğunuz erişeni sınıfını kullanarak komut yürüten bir CCommand sınıfını oluşturun. CCommand sınıfı, aşağıdakine benzer:
    class CQuery1 : public CCommand<CAccessor<CQuery1Accessor> >
    {
    public:
    	HRESULT Open()
    	{
    		HRESULT		hr;
    
    
    		hr = OpenDataSource();
    		if (FAILED(hr))
    			return hr;
    
    		return OpenRowset();
    	}
    	HRESULT OpenDataSource()
    	{
    		HRESULT		hr;
    		CDataSource db;
    		CDBPropSet	dbinit(DBPROPSET_DBINIT);
    
    		dbinit.AddProperty(DBPROP_AUTH_PERSIST_SENSITIVE_AUTHINFO, false);
    		dbinit.AddProperty(DBPROP_INIT_CATALOG, OLESTR("yourdatabase"));
    		dbinit.AddProperty(DBPROP_INIT_DATASOURCE, OLESTR("yourserver"));
    		dbinit.AddProperty(DBPROP_INIT_LCID, (long)1033);
    		dbinit.AddProperty(DBPROP_INIT_PROMPT, (short)4);
    		dbinit.AddProperty(DBPROP_AUTH_PASSWORD, "");
    		dbinit.AddProperty(DBPROP_AUTH_USERID, "sa");
    
    		hr = db.Open(_T("SQLOLEDB"), &dbinit);
    		if (FAILED(hr))
    			return hr;
    
    		return m_session.Open(db);
    	}
    	HRESULT OpenRowset()
    	{
    		// Set properties for open
    		LPCTSTR szCommand = NULL;
    		HRESULT hr = S_OK;
    		hr = _CommandClass::GetDefaultCommand(&szCommand);
    		if (FAILED(hr))
    			return hr;
    		hr = CreateCommand(m_session);
    		if (SUCCEEDED(hr))
    		{
    			CComPtr<ICommandText> spCommandText;
    			hr = m_spCommand->QueryInterface(&spCommandText);
    			USES_CONVERSION;
    			if (SUCCEEDED(hr))
    			hr = spCommandText->SetCommandText(DBGUID_SQL, T2COLE(szCommand));
    		}
    /* --------------  Adding this code prevents the error:
    		ULONG ulOrds[]={1};
                    DBPARAMBINDINFO ParamInfo[1];
    
    		ParamInfo[0].pwszDataSourceType = (unsigned short *) L"DBTYPE_I4";
    		ParamInfo[0].bPrecision = 10;
    		ParamInfo[0].bScale = 0;
    		ParamInfo[0].dwFlags = DBPARAMFLAGS_ISINPUT;
    		ParamInfo[0].pwszName = NULL;
    
    		ParamInfo[0].ulParamSize = sizeof(LONG);
    
    		hr = SetParameterInfo(1, ulOrds, ParamInfo);
    ----------------*/ 
    		hr = Prepare(); //// hr =  E_FAIL without SetParameterInfo call
    		if (E_FAIL == hr)
    		{
    			AtlTraceErrorRecords();
    			return E_FAIL;
    		}
    
    		m_field1param = 0;
    		hr = CCommand<CAccessor<CQuery1Accessor> >::Open();
    		return hr;
    	}
    	CSession	m_session;
    };
    
    
    						
    Yukarıdaki kod açıklamaları E_FAIL döndürülüyor gelen Prepare() engellemeye SetParameterInfo() çağıran kod geçici kaldırın.
  4. Son olarak, bazı kod uygulamanızda sorguyu açar ekleyin:
    	CoInitialize(NULL);
    	CQuery1 rs;
    	rs.Open();
    	rs.MoveFirst();
    						

Bu makaledeki bilginin uygulandığı durum:
  • Microsoft OLE DB Provider for SQL Server 7.01, Ne zaman ne ile kullanilir:
    • Microsoft Data Access Components 2.0
    • Microsoft Data Access Components 2.1
    • Microsoft Data Access Components 2.5
    • Microsoft Data Access Components 2.6
    • Microsoft Data Access Components 2.7
  • Microsoft OLE DB Provider for SQL Server 7.0, Ne zaman ne ile kullanilir:
    • Microsoft Data Access Components 2.0
    • Microsoft Data Access Components 2.1
    • Microsoft Data Access Components 2.5
    • Microsoft Data Access Components 2.6
    • Microsoft Data Access Components 2.7
Anahtar Kelimeler: 
kbmt kbconsumer kbdatabase kbdtl kbprb KB235053 KbMttr
Otomatik TercümeOtomatik Tercüme
ÖNEMLİ: Bu makale, bir kişi tarafından çevrilmek yerine, Microsoft makine-çevirisi yazılımı ile çevrilmiştir. Microsoft size hem kişiler tarafından çevrilmiş, hem de makine-çevrisi ile çevrilmiş makaleler sunar. Böylelikle, bilgi bankamızdaki tüm makalelere, kendi dilinizde ulaşmış olursunuz. Bununla birlikte, makine tarafından çevrilmiş makaleler mükemmel değildir. Bir yabancının sizin dilinizde konuşurken yapabileceği hatalar gibi, makale; kelime dağarcığı, söz dizim kuralları veya dil bilgisi açısından yanlışlar içerebilir. Microsoft, içeriğin yanlış çevrimi veya onun müşteri tarafından kullanımından doğan; kusur, hata veya zarardan sorumlu değildir. Microsoft ayrıca makine çevirisi yazılımını sıkça güncellemektedir.
Makalenin İngilizcesi aşağıdaki gibidir:235053  (http://support.microsoft.com/kb/235053/en-us/ )