Vous pouvez utiliser certains moteurs d'analyse de Microsoft pour T-SQL. Vous pouvez les trouver dans les assemblages Microsoft.Data.Schema.ScriptDom.dll
et Microsoft.Data.Schema.ScriptDom.Sql.dll
.
TSql100Parser parser = new TSql100Parser(false);
IList<ParseError> errors;
Expression expr = parser.ParseBooleanExpression(
new StringReader(condition),
out errors
);
if (errors != null && errors.Count > 0)
{
// Error handling
return;
}
Si vous n'obtenez aucune erreur, la chaîne est une expression de filtre valide. Bien qu'il puisse y avoir des expressions nuisibles.
Si vous le souhaitez, vous pouvez exécuter l'expression à travers votre propre visiteur pour détecter les constructions indésirables (telles que les sous-requêtes). Mais sachez que vous devrez remplacer la plupart des 650 surcharges, pour Visit(...)
et ExplicitVisit(...)
. Les classes partielles seraient bien ici.
Lorsque vous êtes satisfait, pourrait alors construire une déclaration SELECT
complète, avec toutes les expressions:
var schemaObject = new SchemaObjectName();
schemaObject.Identifiers.Add(new Identifier {Value = "MyTable"});
var queryExpression = new QuerySpecification();
queryExpression.FromClauses.Add(
new SchemaObjectTableSource {SchemaObject = schemaObject});
// Add the expression from before (repeat as necessary)
Literal zeroLiteral = new Literal
{
LiteralType = LiteralType.Integer,
Value = "0",
};
Literal oneLiteral = new Literal
{
LiteralType = LiteralType.Integer,
Value = "1",
};
WhenClause whenClause = new WhenClause
{
WhenExpression = expr, // <-- here
ThenExpression = oneLiteral,
};
CaseExpression caseExpression = new CaseExpression
{
ElseExpression = zeroLiteral,
};
caseExpression.WhenClauses.Add(whenClause);
queryExpression.SelectElements.Add(caseExpression);
var selectStatement = new SelectStatement {QueryExpression = queryExpression};
...et tournez tout dans une chaîne:
var generator = new Sql100ScriptGenerator();
string query;
generator.GenerateScript(selectStatement, out query);
Console.WriteLine(query);
Sortie: pour exécuter quelques
SELECT CASE WHEN ITEM_ID = 1
OR (ITEM_NAME LIKE 'something'
AND ITEM_PRICE > 123
AND (ITEM_WEIGHT = 456
OR ITEM_HEIGHT < 789)) THEN 1 ELSE 0 END
FROM MyTable
Si cette expression est trop grand pour manipuler, vous pouvez toujours diviser les règles en morceaux, au temps.
Bien que, pour être autorisé à redistribuer les fichiers Microsoft.Data.Schema.ScriptDom.*.dll
, vous devez posséder une licence de Visual Studio Team System (Est-ce inclus dans au moins VS Pro/Édition Intégrale?)
Lien: http://blogs.msdn.com/b/gertd/archive/2008/08/22/redist.aspx
Alors vous allez vérifier 100 000 règles à chaque validation ...? – Chains
La question est un peu vague, vos "règles" ne sont qu'une série de clauses WHERE, n'est-ce pas? Qu'est-ce que vous essayez exactement de tester (que chaque clause renvoie 0?). En outre, vous avez dit que vous avez plus de 1000 règles (où clauses), est-ce que votre objectif est de les exécuter toutes et de vérifier qu'elles donnent toutes 0 résultats? Comment voulez-vous/prévoyez-vous gérer les échecs? – Zachary
Est-ce qu'on parle de contraintes ou de conditions dans la clause where? –