Skip to content

Commit 44f5091

Browse files
authored
Merge pull request #5 from gmarginet/2-sql-string-can-not-be-generated-when-a-defined-parameter-is-used-more-then-once-in-the-query
Fix issue with using parameter more then once in query
2 parents de46bf0 + 8ecaee9 commit 44f5091

File tree

4 files changed

+30
-6
lines changed

4 files changed

+30
-6
lines changed

src/SqlQueryTools/FileHandlers/SqlSaveHandler.cs

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,8 @@ private async Task GenerateSqlConstStringAsync(string inputFilePath)
8686

8787
var hasDeclarationSection = sqlParserTokens.Any(x => x.TokenType == TSqlTokenType.SingleLineComment && x.Text == options.EndOfParameterDeclarationMarker);
8888
var endOfParameterDeclarationMarkerFound = false;
89-
var parameterNames = new List<string>();
89+
var declaredParameters = new Dictionary<string,string>();
90+
var foundParameterDeclaration = String.Empty;
9091
var sqlCodeBuilder = new StringBuilder();
9192
var whiteSpaceBuffer = new StringBuilder();
9293
foreach (var token in sqlParserTokens)
@@ -101,9 +102,16 @@ private async Task GenerateSqlConstStringAsync(string inputFilePath)
101102

102103
if (token.TokenType == TSqlTokenType.Variable)
103104
{
104-
parameterNames.Add(token.Text);
105+
foundParameterDeclaration = token.Text;
106+
declaredParameters.Add(foundParameterDeclaration, string.Empty);
105107
continue;
106108
}
109+
110+
if (token.TokenType == TSqlTokenType.Identifier && !string.IsNullOrEmpty(foundParameterDeclaration))
111+
{
112+
declaredParameters[foundParameterDeclaration] = token.Text;
113+
foundParameterDeclaration = string.Empty;
114+
}
107115
}
108116
else
109117
{
@@ -131,6 +139,15 @@ private async Task GenerateSqlConstStringAsync(string inputFilePath)
131139
continue;
132140
}
133141

142+
if (token.TokenType == TSqlTokenType.Variable)
143+
{
144+
if (!declaredParameters.ContainsKey(token.Text))
145+
{
146+
await outputPane.WriteLineAsync($"\tVariable {token.Text} is used in the query, but it is not defined in the 'Parameter Declarat");
147+
return;
148+
}
149+
}
150+
134151
if (whiteSpaceBuffer.Length > 0)
135152
{
136153
sqlCodeBuilder.Append(whiteSpaceBuffer.ToString());
@@ -155,7 +172,13 @@ private async Task GenerateSqlConstStringAsync(string inputFilePath)
155172
await conn.OpenAsync();
156173
try
157174
{
158-
conn.Query($"DECLARE @sql NVARCHAR(MAX) = '{sqlCode.Replace("'", "''")}'; EXEC sp_describe_first_result_set @sql;");
175+
//conn.Query($"DECLARE @sql NVARCHAR(MAX) = '{sqlCode.Replace("'", "''")}'; EXEC sp_describe_first_result_set @sql;");
176+
//conn.Query($"DECLARE @sql NVARCHAR(MAX) = '{sqlCode.Replace("'", "''")}'; DECLARE @params NVARCHAR(MAX) = '{string.Join(", ", declaredParameters.Select(x => $"{x.Key} {x.Value}"))}'; EXEC sp_describe_first_result_set @sql, @params;").ToList();
177+
var queryBuilder = new StringBuilder();
178+
queryBuilder.AppendLine($"DECLARE @sql NVARCHAR(MAX) = '{sqlCode.Replace("'", "''")}';");
179+
queryBuilder.AppendLine($"DECLARE @params NVARCHAR(MAX) = '{string.Join(", ", declaredParameters.Select(x => $"{x.Key} {x.Value}"))}';");
180+
queryBuilder.AppendLine("EXEC sp_describe_first_result_set @sql, @params;");
181+
conn.Query(queryBuilder.ToString()).ToList();
159182
}
160183
catch (SqlException ex)
161184
{
@@ -211,7 +234,7 @@ private async Task GenerateSqlConstStringAsync(string inputFilePath)
211234
contentBuilder.AppendLine($"\t{{");
212235
contentBuilder.AppendLine($"\t\tpublic const string Query = @\"{sqlCode}\";");
213236

214-
foreach (var name in parameterNames)
237+
foreach (var name in declaredParameters.Keys)
215238
{
216239
contentBuilder.AppendLine();
217240
contentBuilder.AppendLine($"\t\tpublic const string {name} = @\"{name}\";");

src/SqlQueryTools/VSCommandTable.vsct

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
<Menu guid="SqlQueryTools" id="SqlQueryToolsMenu" priority="0x0100" type="Menu">
2121
<Parent guid="SqlQueryTools" id="SqlQueryToolsMenuGroup"/>
2222
<CommandFlag>DefaultInvisible</CommandFlag>
23+
<CommandFlag>DynamicVisibility</CommandFlag>
2324
<Strings>
2425
<ButtonText>Sql Query Tools</ButtonText>
2526
</Strings>

src/SqlQueryTools/source.extension.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ internal sealed partial class Vsix
1111
public const string Name = "SqlQueryTools";
1212
public const string Description = @"Generate class with string based on Sql file content.";
1313
public const string Language = "en-US";
14-
public const string Version = "1.1";
14+
public const string Version = "1.2";
1515
public const string Author = "Gert Marginet";
1616
public const string Tags = "";
1717
}

src/SqlQueryTools/source.extension.vsixmanifest

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<PackageManifest Version="2.0.0" xmlns="http://schemas.microsoft.com/developer/vsx-schema/2011" xmlns:d="http://schemas.microsoft.com/developer/vsx-schema-design/2011">
33
<Metadata>
4-
<Identity Id="SqlQueryTools.46119220-B112-4974-BF62-BA76F5548B13" Version="1.1" Language="en-US" Publisher="Gert Marginet" />
4+
<Identity Id="SqlQueryTools.46119220-B112-4974-BF62-BA76F5548B13" Version="1.2" Language="en-US" Publisher="Gert Marginet" />
55
<DisplayName>SqlQueryTools</DisplayName>
66
<Description xml:space="preserve">Generate class with string based on Sql file content.</Description>
77
<MoreInfo>http://github.com/gmarginet/SqlQueryTools</MoreInfo>

0 commit comments

Comments
 (0)