検索

InterSystems公式
· 2025年8月13日

Desafio InterSystems no MIT Hacking Medicine 2025 !

Olá Comunidade! 

Este é um desafio técnico aberto a todos os participantes do hackathon MIT Hacking Medicine:

Melhor Uso do GenAI com a Busca Vetorial da InterSystems

Ao encarar seu desafio na área da saúde neste fim de semana, pense em como a IA Generativa pode aumentar a eficácia e a inteligência da sua solução.

Siga os passos do repositório GitHub do InterSystems IRIS Vector Search para começar.

Os mentores da InterSystems estarão no local para ajudar você a começar e implementar.

Esperamos por vocês 😉

Acesse Desafio InterSystems no MIT Hacking Medicine 2025 em São Paulo - BR  para mais informações!

1 Comment
ディスカッション (1)2
続けるにはログインするか新規登録を行ってください
記事
· 2025年8月13日 8m read

Utilisation de LIKE avec des variables et des modèles dans SQL

Au fil des ans, j'ai constaté que certaines questions SQL revenaient régulièrement au sein de la Communauté des développeurs InterSystems, notamment concernant l'utilisation du prédicat LIKE dans différents contextes. Parmi les variantes courantes, on peut citer :

et bien d'autres dérivés. J'ai donc décidé d'écrire un article consacré au fonctionnement de LIKE dans InterSystems IRIS SQL, notamment lorsqu'il est utilisé avec des variables dans Embedded SQL, Dynamic SQL et les requêtes de classes, tout en abordant l'échappement de motifs et les recherches de caractères spéciaux.

Tout d'abord, je tiens à préciser qu'InterSystems IRIS SQL offre la plupart des fonctionnalités disponibles dans d'autres bases de données relationnelles implémentant une version ultérieure de la norme SQL. Il est toutefois important de préciser qu'outre l'accès relationnel, IRIS permet également d'utiliser d'autres modèles pour obtenir les mêmes données, par exemple des modèles objet ou document.

À ce propos, examinons le prédicat LIKE et son utilisation en SQL pour la recherche de motifs.

Informations de base

Commençons par quelques notions de base. Le prédicat LIKE est utilisé dans une clause WHERE (ou HAVING) d'une instruction SELECT, UPDATE ou DELETE pour filtrer les enregistrements selon que les valeurs d'une colonne correspondent à un motif spécifié. La syntaxe de base est la suivante :

SELECT column1, column2
  FROM table_name
 WHERE column_name LIKE pattern;

Le modèle peut inclure des caractères littéraux et deux caractères génériques principaux :

  • % (signe de pourcentage) : représente zéro, un ou plusieurs caractères. Par exemple, « A% » correspond à toute chaîne commençant par « A », « %Z » à toute chaîne se terminant par « Z » et « %XY% » à toute chaîne contenant « XY ».
  • _ (trait de soulignement) : représente un seul caractère. Par exemple, « A_C » correspond à « ABC », « AEC », etc., mais pas à « AC » ni à « ABBC ».

Par exemple, la requête suivante récupère tous les noms de la table Employés commençant par « Jo » :

SELECT Name
  FROM Employees
 WHERE Name LIKE 'Jo%';

Cette requête récupère tous les noms dont le deuxième caractère est « a » :

SELECT Name
  FROM Employees
 WHERE Name LIKE '_a%';

Il est essentiel de comprendre que LIKE effectue une correspondance de motif, et non une égalité. Bien que 'ABC' LIKE 'ABC' soit évalué comme vrai, il est généralement plus efficace d'utiliser l'opérateur = pour les correspondances exactes de chaînes ('ABC' = 'ABC'). LIKE est idéal pour les correspondances approximatives ou les recherches de sous-chaînes.

Inclure un caractère spécial dans une expression de recherche (clause d'échappement)

Je trouve la clause ESCAPE très pratique lorsque vous devez utiliser un caractère générique, par exemple %, dans votre instruction LIKE, et que vous souhaitez qu'il désigne un signe de pourcentage. Dans ce cas, vous pouvez utiliser la clause ESCAPE pour définir un caractère d'échappement. Tout caractère suivant immédiatement le caractère d'échappement dans le motif est traité comme un caractère littéral, et non comme un caractère générique. Par exemple, si vous disposez des données suivantes :

INSERT INTO Post.Promos(name, description) VALUES('Test 1', 'This is 40% discount')
INSERT INTO Post.Promos(name, description) VALUES('Test 2', 'This is 50% discount')
INSERT INTO Post.Promos(name, description) VALUES('Test 3', 'This is 10% discount')
INSERT INTO Post.Promos(name, description) VALUES('Test 4', 'some description')

et vous souhaitez trouver toutes les promotions dont la description contient l'expression « 50% discount », vous pouvez utiliser la requête suivante :

SELECT Name
  FROM Post.Promos
 WHERE Description LIKE '%50\% discount' ESCAPE '\'

Dans cet exemple, \ est défini comme caractère d'échappement. Le système traitera donc le signe % comme un caractère littéral et non un caractère générique, et recherchera une remise dont la description contient l'expression littérale « 50% discount ».

Recherche de caractères spéciaux

Si vous devez rechercher plusieurs caractères spéciaux ou tous les trouver dans une chaîne, vous ne pouvez pas utiliser le prédicat LIKE ; vous devez utiliser %MATCHES. Ce prédicat correspond à une valeur avec une chaîne de caractères contenant des caractères littéraux, des caractères génériques et des plages. Veuillez noter qu'un motif doit être spécifié au format logique, quel que soit le paramètre %SelectMode. Si vous souhaitez trouver toutes les valeurs contenant un caractère spécial, utilisez %MATCHES :

SELECT * 
  FROM Post.Promos p
 WHERE p.description %MATCHES '*[!”%#$&”()*+,-./:;<=>?@\%\_]*'

Cette fonction recherche toute description contenant au moins un des symboles listés. Vous pouvez utiliser la clause ESCAPE pour spécifier le caractère d'échappement, mais par défaut, il est défini sur « \" ; vous pouvez donc l'omettre, comme dans mon exemple.

La requête ci-dessus renvoie trois lignes avec des remises de 40 %, 50 % et 10 %, et non « some description ».

De plus, ce prédicat suit les règles générales de correspondance de motifs d'IRIS. Par exemple, pour un espace réservé, vous utiliserez « ? » et non « _ » :

SELECT * 
  FROM Post.Promos p
 WHERE p.name %MATCHES '???? [0-9]'

Cette fonction recherchera tous les noms composés de quatre caractères, d'un espace et d'un chiffre.

À propos des modèles, il existe également un prédicat %PATTERN qui permet de faire correspondre un modèle de codes de type de caractère et de littéraux aux valeurs de données. Pour effectuer la même recherche que ci-dessus, vous pouvez écrire la commande suivante :

SELECT * 
  FROM Post.Promos p
 WHERE p.name %PATTERN '1U.L1" "1N'

Correspondances :

1U — 1 lettre majuscule
.L — lettres minuscules
1" " — 1 espace
1N — 1 chiffre

Utilisation de variables avec LIKE

Voyons maintenant comment utiliser les variables dans vos requêtes. Il existe trois façons d'utiliser une instruction SQL dans votre code Object Script : Embedded SQL, Dynamic SQL et écriture d'une requête de classe.

Embedded SQL

Pour transmettre une valeur à une instruction Embedded SQL, vous devez utiliser un paramètre nommé (ou, en d'autres termes, des variables hôtes d'entrée et/ou de sortie), ce qui signifie qu'il doit avoir un nom. Par exemple, si nous souhaitons toujours trouver toutes les promotions avec une réduction de 50 %, nous écrirons la requête suivante :

 set param = "50\% discount"
 &sql(DECLARE C1 CURSOR FOR
       SELECT Name
         INTO :nameout
         FROM Post.Promos
        WHERE Description LIKE '%'_:param_'%' ESCAPE '\')
 &sql(OPEN C1)
       QUIT:(SQLCODE'=0)
 &sql(FETCH C1)
 WHILE (SQLCODE = 0) {
     WRITE nameout,!
    &sql(FETCH C1) }
  &sql(CLOSE C1)

Sa variable hôte d'entrée est param, et elle est égale à « 50% discount ». Pour que la requête comprenne que % fait partie du paramètre et non un espace réservé pour une longueur de caractères, j'utilise la clause ESCAPE.

De plus, veillez à bien placer les guillemets simples et doubles :

  • En SQL, les premiers servent à marquer un champ dont le nom est réservé, par exemple « Groupe ». Les secondes permettent d'observer une chaîne.
  • En ObjectScript, les premiers servent à observer la chaîne, tandis que les seconds n'ont aucun rapport avec les chaînes : c'est un opérateur unaire NOT.

Lorsque vous utilisez des paramètres, il n'est pas nécessaire d'insérer un guillemet simple entre les guillemets doubles.

set param = " '50\% discount ' "

pour indiquer au compilateur qu'il s'agit d'une chaîne. Dans ce cas, le moteur recherchera des guillemets simples dans la chaîne de recherche.

Dans l'exemple ci-dessus, la variable hôte de sortie est « nameout », où sera placée la valeur de la colonne Name. Elle pourra être utilisée ultérieurement dans le code.

SQL dynamique

Depuis la version 2015.2, Dynamic SQL peut accepter une valeur littérale en entrée dans une requête de deux manières :

  • Paramètres d'entrée spécifiés à l'exécution à l'aide du caractère « ? »
  • Variables hôtes d'entrée spécifiées lors de la préparation

La deuxième approche suit le même principe que pour Embedded SQL ci-dessus :

 set param = "50\% discount"
 set myquery = 3
 set tStatement = ##class(%SQL.Statement).%New()
 set myquery(1) = "SELECT Name"
 set myquery(2) = "FROM Post.Promos"
 set myquery(3) = "WHERE Description LIKE '%'_:param_'%' ESCAPE '\'"
 set qStatus = tStatement.%Prepare(.myquery)
 set tResult = tStatement.%Execute()
 while tResult.%Next() {
	 write tResult.Name, !
 }

à l'exception des variables hôtes de sortie, vous n'avez pas besoin de ces variables, car %SQL.StatementResult (type de résultat de tStatement.%Execute()) contiendra toutes les propriétés qui référencent les colonnes de l'instruction SELECT.

Dans la première approche, vous remplacez un paramètre par un point d'interrogation, puis, lors de l'appel de %Execute(), vous devez fournir les valeurs des paramètres dans le même ordre que le « ? » dans votre instruction :

 set param = "50\% discount"
 set myquery = 3
 set tStatement = ##class(%SQL.Statement).%New()
 set myquery(1) = "SELECT Name"
 set myquery(2) = "FROM Post.Promos"
 set myquery(3) = "WHERE Description LIKE '%'_?_'%' ESCAPE '\'"
 set qStatus = tStatement.%Prepare(.myquery)
 set tResult = tStatement.%Execute(param)
 while tResult.%Next() {
	 write tResult.Name, !
 }

Requête de classe

Les variables hôtes d'entrée sont utilisées dans les requêtes de classe selon les mêmes règles que dans le SQL embarqué et le Dynamic SQL :

Query GetDiscount(param As %String) As %SQLQuery [ SqlProc ]
{
SELECT Name FROM Post.Promos
 WHERE (Description LIKE '%'_:param_'%' ESCAPE '\')
}

Lors de l'appel de la requête, vous fournissez les paramètres dans l'ordre où ils sont écrits dans la signature de la méthode :

SELECT *
  FROM Post.Promos_GetDiscount('50\% discount')

J'espère que cet article répondra à certaines des questions fréquentes qui reviennent de temps à autre.

Si vous souhaitez lire un article plus approfondi sur les considérations de performance et les bonnes pratiques, ou si vous avez des commentaires, n'hésitez pas à les laisser dans la section commentaires ci-dessous.

ディスカッション (0)1
続けるにはログインするか新規登録を行ってください
質問
· 2025年8月13日

Inconsistency in Caché Database: Mismatch Between Total Count Based on Unique Identifiers, Deduplicated Count, and Conditional Query Results

In the Caché database, when calculating the total count based on the unique identifier of a record, the quantity is over 1.2 million. After removing duplicates based on the unique identifier and then calculating the total count, the quantity is over 400,000. When grouping by the unique identifier, it can be observed that the count for this identifier is not one. However, when performing a conditional query based on the identifier, only one record can be retrieved. Why is this the case?

7 Comments
ディスカッション (7)3
続けるにはログインするか新規登録を行ってください
記事
· 2025年8月13日 3m read

$ZF(-100) で指定できる便利なキーワード

これは InterSystems FAQ サイトの記事です。

$ZF(-100) は、OSコマンドまたはプログラムを子プロセスとして実行するのに使われますが、一緒に便利なキーワードを指定することが可能です。

$ZF(-100)でコマンドの実行がうまくできない、という経験をされた方も多いかと思います。

そんな時は、この便利なキーワードを使って原因の調査をしていきましょう。

キーワードには以下のようなものがあります。

/SHELL シェルを使用して program を実行する。既定では、シェルは使用されない。
/STDIN=filename 入出力リダイレクト入力ファイル
/STDOUT=filename 入出力リダイレクト標準データ出力ファイル
/STDERR=filename 入出力リダイレクト標準エラー出力ファイル
/LOGCMD 結果として得られるコマンド行を messages.log に記録する
/NOQUOTE コマンド、コマンド引数、またはファイル名の自動引用を禁止する


使用方法は、以下のようになります。

write $zf(-100,"/SHELL /LOGCMD /STDERR=err.log","command1","command2",...) 


例:ネットワーク共有の設定がうまくいかないので原因を調べたい。
  →STDERR キーワードで、入出力リダイレクト標準エラー出力ファイルを取得してみる

TEST1>write $zf(-100,"/SHELL /stdout=output.log /stderr=err.log","net", "use", "\\172.xxx.xxx.xxx\c$", "/user:Administrator", ^pass)
1
TEST1>!type err.log
システム エラー 86 が発生しました。
指定されたネットワーク パスワードが間違っています。
'5cm' は、内部コマンドまたは外部コマンド、
操作可能なプログラムまたはバッチ ファイルとして認識されていません。

これは、ネットワーク共有にアクセスするパスワードに & などの特殊文字含まれるため、パスワードが途中の 5cm までしか認識しなかった例です。
この場合は、^&でエスケープするか、/NOQUOTE キーワードを指定し、パスワードにクオートをつけて対応します)
※クオートいるなしを、$ZFが勝手に判断するので、本当はいるとき(パスワードに&が含まれるときとか)でも、付けてくれなくてエラーになることがある
そんなときの対応に使える(クオートはあえて付けない=NOQUOTE、いるときは自分でつける)


対応例:

USER>write $zf(-100,"/SHELL /NOQUOTE /stdout=output.log /stderr=err.log","net", "use", "\\172.xxx.xxx.xxx\Public", "/user:Administrator",""""_ ^pass_"""")
0
USER>!net use
新しい接続は記憶されます。
 
 
ステータス  ローカル名 リモート名                ネットワーク名
 
-------------------------------------------------------------------------------
OK                     \\172.xxx.xxx.xxx\Public   Microsoft Windows Network
コマンドは正常に終了しました。
 
USER>
ディスカッション (0)0
続けるにはログインするか新規登録を行ってください
お知らせ
· 2025年8月12日

[Demo Video] Data Transformation Adventures with InterSystems IRIS

#InterSystems Demo Games entry


⏯️ Data Transformation Adventures with InterSystems IRIS

Navigating interoperability and healthcare can be an exciting adventure. In this demo, we will show you how InterSystems IRIS can be the perfect tool to get data - wherever it may lie, in whatever format, into a format of your choice, including FHIR! Once that is done, analytics is a piece of cake with the FHIR SQL Builder and Deep See Web. Let the questing begin!

Presenters:
🗣 @Kate Lau, Sales Engineer, InterSystems
🗣 @Merlin Wijaya, Sales Engineer, InterSystems
🗣 @Martyn Lee, Sales Engineer, InterSystems
🗣 @Bryan Hoon, Sales Engineer, InterSystems

🗳 If you like this video, don't forget to vote for it in the Demo Games!

ディスカッション (0)0
続けるにはログインするか新規登録を行ってください