简体   繁体   中英

Must declare scalar variable with BCP in SQL Server

I have the following section of my stored procedure code and for some reason, I keep getting the error messages:

  1. Must declare scalar variable "@query"
  2. Statement(s) could not be prepared

I am also attempting to use BCP to export to a file and the @query string is a complex string. Here's the code:

@market varchar(20) = null, 

@date datetime = null


AS
BEGIN
    SET NOCOUNT ON;

 set @date =

 CASE datepart(dw,getdate())

 WHEN 1 THEN dateadd(day, -1, convert(varchar, getdate(), 101))

 WHEN 2 THEN dateadd(day, -2, convert(varchar, getdate(), 101))

 WHEN 3 THEN dateadd(day, -3, convert(varchar, getdate(), 101))

 WHEN 4 THEN dateadd(day, -4, convert(varchar, getdate(), 101))

 WHEN 5 THEN dateadd(day, -5, convert(varchar, getdate(), 101))

 WHEN 6 THEN dateadd(day, +0, convert(varchar, getdate(), 101))

 WHEN 7 THEN dateadd(day, -7, convert(varchar, getdate(), 101))

 END
  --Set @date = '2014-12-27 00:00:00.000'
  Select @date  -- Latest Saturday (Day Number)
  SELECT CONVERT(CHAR(8), @date, 112)
  declare @query VARCHAR(4000)

 SELECT @query = 'select ''"'' + CONVERT(varchar,fo.orderno) + ''"'' as [STOP_ID], 
  CASE WHEN (isnull(i.pickuptime,'''') <> '''') THEN convert(datetime,i.pickuptime,126) ELSE convert(datetime,fo.pickeduptime,126) END as [PICKUP_TIME], 
  CASE WHEN (isnull(i.deliveredtime,'''') <> '''') THEN convert(datetime,i.deliveredtime,126) ELSE convert(datetime,fo.deliveredtime,126) END as [DELIVERY_TIME], 
  CASE WHEN (isnull(i.pickupcontact,'''') <> '''') THEN ''"'' + i.pickupcontact + ''"'' ELSE ''"'' + og.marketsitenumber + ''"'' END as [SENDER_CODE], 
  CASE WHEN (isnull(i.pickupcompany,'''') <> '''') THEN ''"'' + i.pickupcompany + ''"'' ELSE ''"'' + fo.pickupcompanyname + ''"'' END as [SENDER_NAME], 
  ''"'' + (CONVERT(varchar, fo.PickupstreetNo) + '' '' + fo.PickupStreet + '' '' + fo.PickupUnit) + ''"'' as [SENDER_STREET], 
  ''"'' + fo.pickupcity + ''"'' as [SENDER_CITY], 
  ''"'' + fo.pickupprovince + ''"'' as [SENDER_STATE], 
  ''"'' + fo.pickuppostalcode + ''"'' as [SENDER_POSTAL_CODE], 
  ''"US"'' as [SENDER_COUNTRY], 
  CASE WHEN (isnull(i.driver,'''') <> '''') THEN ''"'' + i.driver + ''"'' ELSE ''"'' + CONVERT(varchar,fo.pickupdriver) + ''"'' END as [DRIVER_ID], 
  CASE WHEN (isnull(i.deliveryfacilitycode,'''') <> '''') THEN ''"'' + i.deliveryfacilitycode + ''"'' ELSE ''""'' END as [RECIPIENT_CODE], --Issue for left-joined "FO Only" records:  No safety net. 
  CASE WHEN (isnull(i.deliverycompanyname,'''') <> '''') THEN ''"'' + i.deliverycompanyname + ''"'' ELSE ''"'' + fo.deliverycompanyname + ''"'' END as [RECIPIENT_NAME], 
  ''"'' + (CONVERT(varchar, fo.deliverystreetNo) + '' '' + fo.DeliveryStreet + '' '' + fo.DeliveryUnit) + ''"'' as [RECIPIENT_STREET], 
  ''"'' + fo.deliverycity + ''"'' as [RECIPIENT_CITY], 
  ''"'' + fo.deliveryprovince + ''"'' as [RECIPIENT_STATE], 
  ''"'' + fo.deliverypostalcode + ''"'' as [RECIPIENT_POSTAL_CODE], 
  ''"US"'' as [RECIPIENT_COUNTRY_CODE], 
  CASE WHEN (og.accounttype = ''stat'' and st.servicetypeid in (''324'',''154'',''156'',''122'',''303'',''290'')) THEN ''"STAT"'' 
        WHEN ((og.accounttype = ''stat'' and st.servicetypeid in (''186'',''304'',''305'')) or (og.accounttype = ''scheduled'' and fo.[route] in (''B1'',''B2'',''B3'',''B4''))) THEN ''"MULTI-STAT"'' 
        WHEN (fo.route not like ''LH%'' and og.accounttype = ''scheduled'' and st.servicetypeid not in (''329'') and fo.[route] not in (''B1'',''B2'',''B3'',''B4'')) THEN ''"ROUTE"'' 
        WHEN ((og.accounttype = ''scheduled'' and st.servicetypeid in (''329'')) or (og.accounttype = ''stat'' and st.servicetypeid in (''372'',''373'',''374'',''377'',''386'',''329'',''356'',''387'',''388'',''389'',''390'',''391'',''392''))) THEN ''"SWEEP"'' 
        WHEN (og.accounttype = ''scheduled'' and fo.route like ''LH%'') THEN ''"LINE-HAUL"'' 
        ELSE ''"PLEASE CONTACT PDI IT WITH THIS STOP_ID"'' END as [DELIVERY_TYPE], 
  CASE WHEN (fo.route not like ''LH%'' and og.accounttype = ''scheduled'' and st.servicetypeid not in (''329'') and fo.[route] not in (''B1'',''B2'',''B3'',''B4'')) THEN ''"'' + fo.reference + ''"'' ELSE ''""'' END as [ROUTE_REFERENCE], 
  CASE WHEN (fo.route not like ''LH%'' and og.accounttype = ''scheduled'' and st.servicetypeid not in (''329'') and fo.[route] not in (''B1'',''B2'',''B3'',''B4'')) THEN ''"0"'' ELSE ''"'' + convert(varchar,fo.distance) + ''"'' END as [MILEAGE], 
  CASE WHEN ((og.accounttype = ''scheduled'') or (og.accounttype = ''stat'' and fo.servicetypeid in (329))) THEN ''"'' + convert(varchar,fo.waitingtimedriver1) + ''"'' ELSE ''"0"'' END as [WAIT_TIME], 
  ''""'' as [WAIT_START_TIME],    --"The time the courier began waiting after the grace period."  Not currently captured anywhere in system. 
  CASE WHEN (((og.accounttype = ''scheduled'') or (og.accounttype = ''stat'' and fo.servicetypeid in (329))) and fo.waitingtimedriver1 > 0) THEN ''"'' + fo.reference + ''"'' ELSE ''""'' END as [WAIT_TIME_ROUTE_REFERENCE], 
  ''""'' as [ARRIVAL_TIME], --"The time the courier arrived at the Pharmacy to pick up the shipment.  REQUIRED in the case of wait time."  Not currently captured anywhere in system. 
  ''""'' as [DEPARTURE_TIME], ----"The time the courier departed from the Pharmacy with the shipment.  REQUIRED in the case of wait time."  Not currently captured anywhere in system. 
  ''"USD"'' as [CURRENCY], 
  ''"0"'' as [FUEL_SURCHARGE], 
  ''"0"'' as [TAX], 
  ''"0"'' as [HOSPICE_CHARGE], 
  ''"0"'' as [MISC_CHARGE], 
  ''"'' + convert(varchar,fo.totalamount) + ''"'' as [TOTAL_CHARGE] 
  from finalizedorders fo 
inner join servicetypes st on fo.servicetypeid = st.servicetypeid 
inner join aropentransactions at on fo.invoicenumber = at.transactionnumber 
inner join OBR_Generator og on og.AccountNumber = fo.AccountNumber 
LEFT JOIN OrderSearchView osv ON fo.OrderNo = osv.[Order No] 
  LEFT JOIN [IRIS\SQLEXPRESS].IDSImport.dbo.IDSData i ON osv.[Cust. Field 2] = i.TripID 
where og.Market = ''Columbus'' 

and at.transactiondate = ''20150124'' --Previous Saturday (Always) 
    and fo.totalamount > 0 
    and og.accounttype <> ''invoice''


queryout "C:\bcptest.txt" -T -c -t,'

PRINT @query

EXEC xp_cmdshell 'bcp @query queryout "C:\bcptest.txt" -T -c -t,'



END

@DBNull is correct. You need to change the actual execution of the bcp command to something like this....

SET @query = 'bcp "' + @query + '" queryout "C:\bcptest.txt" -T -c -t,';
EXEC xp_cmdshell @query;

You need to wrap the query in quotes, and there's a limit of varchar(8000) or nvarchar(4000) on the actual command you can execute with xp_cmdshell. I would suggest you consider wrapping your query in a view or a stored procedure. Not only would that greatly enhance the maintainability of the code, but you wouldn't need to worry about the size limit, not to mention all the single quote escaping you're having to do now.

Hope that helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM