SQL Server Is it possible to run a stored procedure with python, then run a BCP command against the results?

cu6pst1q  于 2023-06-28  发布在  Python
关注(0)|答案(1)|浏览(151)

I have been tasked with pulling data from a server, but I need to replicate the results of what is currently running. What used to happen is the SQL file would run the stored procedure, and at the end of the procedure is the BCP i have at the end of the python script now(it is still included here in the SP-just incase).

Assuming the values below were real, is it possible to run the sql file with python-which would call the stored procedure on that target server, then using those results somehow run a BCP against them to create the output files? The servers are Trusted with each other-if that helps....

Database Name = TestDatabase

Stored Procedure = ExtractData

Python Script = RunThisPlease.py

Python Script-as is, does NOT work as it cannot read the data returned from the SQL file + stored procedure into the following BCP command

  1. #############RunThisPlease.py
  2. import pyodbc
  3. import os
  4. import re
  5. import subprocess
  6. import bcp
  7. import sys
  8. fd = open('D:\PathTo\SQLScript.sql', 'r')
  9. print("Reading File")
  10. sqlFile = fd.read()
  11. fd.close()
  12. conn = pyodbc.connect('Driver={SQL Server};'
  13. 'Server=11.111.111.11;'
  14. 'Database=TestDatabase;'
  15. 'Trusted_Connection=yes;')
  16. cursor = conn.cursor()
  17. values = cursor.execute(sqlFile)
  18. command = 'bcp select BATDAT, BATSEQ,SEQNBR,DIH,RCPDAT, ProviderID, ProviderName, TotalBilledAmount, ClaimStatus, ClaimSource, LOBCompany, GroupName, CASE WHEN Messagecodes is NULL THEN ' + '''' + '''' + ' 'ELSE Messagecodes END from ##openpendreportingdata order by rowid queryout \\rootpath\to\target\directory\ThisOutputFileNameShouldMatchTheStoredProcedureName.txt -c -t, -T -S'

How can i run this command above? it LOOKS ok, but will fail because of temp table ##openpendreportingdata

SQL file that has been calling the stored procedure(ran from the same server as the target database):

  1. SQLscript.sql:
  2. USE [TestDatabase]
  3. DECLARE @return_value int
  4. EXEC @return_value = [dbo].[ExtractData]
  5. @filelocation = N'\\rootpath\to\target\directory\'
  6. SELECT 'Return Value' = @return_value

Actual Stored Procedure

  1. ExtractData
  2. USE [TestDatabase]
  3. GO
  4. /****** Object: StoredProcedure [dbo].[ExtractData] Script Date: 6/2/2023 5:28:16 PM ******/
  5. SET ANSI_NULLS ON
  6. GO
  7. SET QUOTED_IDENTIFIER ON
  8. GO
  9. ALTER PROCEDURE [dbo].[ExtractData] @filelocation VARCHAR(200)
  10. /*****
  11. Date Issue Developer Change Description
  12. ---- ----- --------- ------------------
  13. 09/16/2020 RHPD-4674 DevName Add LOBC and Group to the select layout after the claim source
  14. Changes include
  15. 1) Top 5 Open Messages (Sorted using that table mentioned in the scope document 0-99)
  16. 2) Ordered by receive date (ascending) then by claim number
  17. 3) Only includes Claims not posted (<> 'P')
  18. 4) Columns
  19. 1) Batdat
  20. 2) Batseq
  21. 3) Seqnbr
  22. 4) DIH (Current Date - Received Date)
  23. 5) Received Date
  24. 6) Provider ID
  25. 7) Provider Name
  26. 8) Total Billed Amount
  27. 9) Claims Status
  28. 10) Claim Source
  29. 11) LOBC **RHPD-4674 (CP)
  30. 12) GroupName **RHPD-4674 (CP)
  31. 11) Message Codes (1 through 5)
  32. *****/
  33. AS
  34. DECLARE
  35. @QueryStmt VARCHAR(8000),
  36. @filename VARCHAR(100),
  37. @dbname VARCHAR(100);
  38. SET NOCOUNT ON
  39. Begin
  40. If @filelocation is null
  41. set @filelocation = 'c:\testing\'
  42. SELECT @dbname = DBNAME FROM [dbo].[SYSFIL]
  43. If @filename is null
  44. set @filename = @dbname + '- ExtractData - ' + CAST(CONVERT(nvarchar(10), GETDATE(), 112) as varchar(30)) + '.csv'
  45. IF OBJECT_ID (N'tempdb.dbo.#openpendtempmsgtable', N'U') IS NOT NULL
  46. Drop table #openpendtempmsgtable
  47. IF OBJECT_ID (N'tempdb.dbo.##openpendreportingdata', N'U') IS NOT NULL
  48. Drop table ##openpendreportingdata
  49. SELECT Distinct
  50. CLAIMTYPE,
  51. BATDAT,
  52. BATSEQ,
  53. SEQNBR,
  54. RCPDAT,
  55. DIH,
  56. ProviderId,
  57. ProviderName,
  58. TotalBilledAmount,
  59. ClaimStatus,
  60. ClaimSource,
  61. LOBCompany, --**RHPD-4674 (CP)
  62. GroupName, --**RHPD-4674 (CP)
  63. MSGCOD,
  64. messagePriority,
  65. rowid
  66. INTO #openpendtempmsgtable
  67. FROM
  68. (
  69. (Select
  70. DISTINCT 'U' CLAIMTYPE,
  71. F.BATDAT,
  72. F.BATSEQ,
  73. F.SEQNBR,
  74. F.RCPDAT,
  75. datediff(day, Convert(date,F.RCPDAT), Convert(date, getdate())) DIH,
  76. P.PRVCOD ProviderId,
  77. REPLACE (P.DSCRPT, ',', ' ') ProviderName,
  78. F.TOTCLA TotalBilledAmount,
  79. F.STSCOD ClaimStatus,
  80. CASE
  81. WHEN F.EDI_FLAG = '8' THEN 'HIPAA 837'
  82. WHEN F.EDI_FLAG = 'M' THEN 'Manual Entry'
  83. WHEN F.EDI_FLAG = 'U' THEN 'Upload'
  84. WHEN F.EDI_FLAG = 'UH' THEN 'Historical Upload'
  85. WHEN F.EDI_FLAG = 'UP' THEN 'Paid Upload'
  86. WHEN F.EDI_FLAG = 'N' THEN 'NCPDP 5.1'
  87. WHEN F.EDI_FLAG = '8E' THEN '837 Estimator'
  88. WHEN F.EDI_FLAG = 'NR' THEN 'NCPDP RTS'
  89. WHEN F.EDI_FLAG = '8O' THEN 'Other 837'
  90. ELSE 'Unknown'
  91. END ClaimSource,
  92. --**RHPD-4674 (CP)
  93. REPLACE (L.DESCRP, ',', ' ') LOBCompany,
  94. REPLACE (G.DSCRPT, ',', ' ') GroupName,
  95. case when (prirty is null or prirty = '') then 999 else convert(integer, prirty) end messagePriority,
  96. ROW_NUMBER() OVER(Partition by F.BATDAT,F.BATSEQ, F.SEQNBR ORDER BY F.BATDAT, F.BATSEQ,F.SEQNBR,case when (prirty is null or prirty = '') then 999 else convert(integer, prirty) End, C.MSGCOD ASC) rowid,
  97. C.MSGCOD
  98. from UMCFIL F WITH (NOLOCK)
  99. Left join dbo.Facfil p
  100. ON f.prvnbr = p.prvcod
  101. INNER JOIN (select distinct BATDAT, BATSEQ, SEQNBR, MSGCOD, STSCOD from CLMMSG WITH (NOLOCK)) C
  102. ON C.BATDAT = F.BATDAT AND C.BATSEQ = F.BATSEQ AND C.SEQNBR = F.SEQNBR
  103. inner join dbo.MCDFIL m on m.msgcod = c.msgcod
  104. --**RHPD-4674 (CP)
  105. left join dbo.LOBCMP L on F.LOBCMP = L.LOBCMP
  106. left join dbo.GRPFIL G on F.GRPNBR = G.GRPNBR
  107. Where C.STSCOD = 'O' AND F.STSCOD <> 'P'
  108. )
  109. union all
  110. (Select
  111. DISTINCT 'H' CLAIMTYPE,
  112. F.BATDAT,
  113. F.BATSEQ,
  114. F.SEQNBR,
  115. F.RCPDAT,
  116. datediff(day, Convert(date,F.RCPDAT), Convert(date, getdate())) DIH,
  117. P.PRVCOD ProviderId,
  118. Replace(case when P.namfor = 'S' then P.lstnam + P.fstnam + P.midnam
  119. when P.namfor = 'L' then rtrim(P.lstnam) + ' ' + P.fstnam
  120. else P.lstkey
  121. end, ',', ' ') as ProviderName,
  122. F.TOTCLA TotalBilledAmount,
  123. F.STSCOD ClaimStatus,
  124. CASE
  125. WHEN F.EDI_FLAG = '8' THEN 'HIPAA 837'
  126. WHEN F.EDI_FLAG = 'M' THEN 'Manual Entry'
  127. WHEN F.EDI_FLAG = 'U' THEN 'Upload'
  128. WHEN F.EDI_FLAG = 'UH' THEN 'Historical Upload'
  129. WHEN F.EDI_FLAG = 'UP' THEN 'Paid Upload'
  130. WHEN F.EDI_FLAG = 'N' THEN 'NCPDP 5.1'
  131. WHEN F.EDI_FLAG = '8E' THEN '837 Estimator'
  132. WHEN F.EDI_FLAG = 'NR' THEN 'NCPDP RTS'
  133. WHEN F.EDI_FLAG = '8O' THEN 'Other 837'
  134. ELSE 'Unknown'
  135. END ClaimSource,
  136. --**RHPD-4674 (CP)
  137. REPLACE (L.DESCRP, ',', ' ') LOBCompany,
  138. REPLACE (G.DSCRPT, ',', ' ') GroupName,
  139. case when (prirty is null or prirty = '') then 999 else convert(integer, prirty) end messagePriority,
  140. ROW_NUMBER() OVER(Partition by F.BATDAT,F.BATSEQ, F.SEQNBR ORDER BY F.BATDAT, F.BATSEQ,F.SEQNBR,case when (prirty is null or prirty = '') then 999 else convert(integer, prirty) End , C.MSGCOD ASC) rowid,
  141. C.MSGCOD
  142. from HMCFIL F WITH (NOLOCK)
  143. Left join dbo.PHYfil p
  144. on f.prvnbr = p.prvcod
  145. INNER JOIN (select distinct BATDAT, BATSEQ, SEQNBR, MSGCOD,STSCOD from CLMMSG WITH (NOLOCK)) C
  146. ON C.BATDAT = F.BATDAT AND C.BATSEQ = F.BATSEQ AND C.SEQNBR = F.SEQNBR
  147. inner join dbo.MCDFIL m on m.msgcod = c.msgcod
  148. --**RHPD-4674 (CP)
  149. left join dbo.LOBCMP L on F.LOBCMP = L.LOBCMP
  150. left join dbo.GRPFIL G on F.GRPNBR = G.GRPNBR
  151. Where C.STSCOD = 'O' AND F.STSCOD <> 'P'
  152. )
  153. ) msg
  154. --Query to Consolidate the message codes
  155. select *
  156. INTO ##openpendreportingdata
  157. from
  158. (
  159. select 'BATCHDATE' as BATDAT,
  160. 'BATCHNUM' as BATSEQ,
  161. 'BATCHSEQ' as SEQNBR,
  162. 'RECEIVEDATE' as RCPDAT,
  163. 'DIH' as DIH,
  164. 'PROVIDERID' as ProviderId,
  165. 'PROVIDERNAME' as ProviderName,
  166. 'TOTALBILLEDAMOUNT' as TotalBilledAmount,
  167. 'CLAIMSTATUS' as ClaimStatus,
  168. 'CLAIMSOURCE' as ClaimSource,
  169. --**RHPD-4674 (CP)
  170. 'LOBCOMPANY' as LOBCompany,
  171. 'GROUPNAME' as GroupName,
  172. 'MSG 1,MSG 2,MSG 3,MSG 4,MSG 5' as Messagecodes,
  173. 0 rowid
  174. union
  175. SELECT DISTINCT CAST(CONVERT(nvarchar(10), BATDAT, 101) as varchar(30)) as BATDAT,
  176. CAST(BATSEQ AS varchar(12)) as BATSEQ,
  177. CAST(SEQNBR AS varchar(12)) as SEQNBR,
  178. CAST(CONVERT(nvarchar(10), RCPDAT, 101) as varchar(30)) AS RCPDAT,
  179. CAST(DIH AS VARCHAR(10)) as DIH,
  180. CASE WHEN ProviderId is NULL THEN ' ' ELSE ProviderId END as ProviderId ,
  181. CASE WHEN ProviderName is NULL THEN ' ' ELSE ProviderName END as ProviderName,
  182. CAST(TotalBilledAmount AS VARCHAR(12)) as TotalBilledAmount,
  183. ClaimStatus as ClaimStatus,
  184. CAST(ClaimSource AS VARCHAR(17)) as ClaimSource,
  185. --**RHPD-4674 (CP)
  186. CASE WHEN LOBCompany is NULL THEN ' ' ELSE LOBCompany END as LOBCompany , --
  187. CASE WHEN GroupName is NULL THEN ' ' ELSE GroupName END as GroupName,
  188. substring(
  189. (
  190. Select ','+a.msgcod AS [text()]
  191. From #openpendtempmsgtable a
  192. Where b.BATDAT = a.BATDAT
  193. and b.BATSEQ = a.BATSEQ
  194. and b.SEQNBR = a.SEQNBR
  195. and a.rowid <= 5
  196. ORDER BY a.rowid
  197. For XML PATH ('')
  198. ), 2, 1000) Messagecodes,
  199. row_number() OVER( ORDER BY RCPDAT, BATDAT, BATSEQ, SEQNBR) rowid
  200. FROM #openpendtempmsgtable b with (nolock)
  201. GROUP BY CLAIMTYPE,
  202. BATDAT,
  203. BATSEQ,
  204. SEQNBR,
  205. RCPDAT,
  206. DIH,
  207. ProviderId,
  208. ProviderName,
  209. TotalBilledAmount,
  210. ClaimStatus,
  211. ClaimSource,
  212. --**RHPD-4674 (CP)
  213. LOBCompany,
  214. GroupName
  215. ) opr
  216. /*
  217. Code here is the code that needs to be replaced:
  218. select @QueryStmt = 'bcp "select BATDAT, BATSEQ,SEQNBR,DIH,RCPDAT, ProviderID, ProviderName, TotalBilledAmount, ClaimStatus, ClaimSource, LOBCompany, GroupName, CASE WHEN Messagecodes is NULL THEN ' + '''' + '''' + ' ELSE Messagecodes END from ##openpendreportingdata order by rowid" queryout "' + @filelocation + @filename + '" -c -t, -T -S'
  219. select @QueryStmt
  220. exec master..xp_cmdshell @QueryStmt
  221. */
  222. End
0s0u357o

0s0u357o1#

As it turns out, the solution involved the calling server not having the needed permissions on the target server to run the BCP command. It does have a trusted connection for sql and stored procedures, but not for windows commands. The solution ended up involving running both bcp queries as select statements, taking the results from a fetchall(), then formatting it to match what the BCP was doing. Please forgive my formatting, im not sure how to make the code block appear and kept getting hit with single lines....

query = "USE [DBNAME] DECLARE @return_value int EXEC @return_value = [Dbname].[dbo].[ExtractData] @filelocation ='N\\rootfilepath\path\to\filelocation\' SELECT 'Return Value' = @return_value"

query2 = "select BATDAT, BATSEQ,SEQNBR,DIH,RCPDAT, ProviderID, ProviderName, TotalBilledAmount, ClaimStatus, ClaimSource, LOBCompany, GroupName, CASE WHEN Messagecodes is NULL THEN \' + '''' + '''' + \' ELSE Messagecodes END from ##temporarytable order by rowid"

cursor.execute(query)

r = cursor.execute(query2)

delimiter = ","

df = r.fetchall()

cursor.close()

outputfile = open(filename, "a")

res = ''

  1. for ele in df:
  2. data = str(ele).replace("'","")
  3. data = str(data).replace('"',"")
  4. data = data.rstrip(")")
  5. data = data.lstrip("(")
  6. datas = data.split(",")
  7. newd = ""
  8. for d in datas:
  9. tempd = d.lstrip()
  10. newd = newd + tempd + ","
  11. newd = newd.rstrip(",")
  12. outputfile.write(newd + "\n")
  13. outputfile.close()`
展开查看全部

相关问题