查找

摘要
· 1 hr 前

Publicações Desenvolvedores InterSystems, Outubro 06 - 12, 2025, Resumo

公告
· 4 hr 前

Winners of the InterSystems .Net, Java, Python, and JavaScript Contest

Hi Community,

It's time to announce the winners of the InterSystems .Net, Java, Python, and JavaScript Contest

Thanks to all our amazing participants who submitted 11 applications 🔥

Now it's time to announce the winners!

Experts Nomination

🥇 1st place and $5,000 go to the golang-fiber-iris-realworld-example-app app by @Dmitry Maslennikov

🥈 2nd place and $2,500 go to the python-iris-audio-query app by @Yu Han Eng

🥉 3rd place and $1,000 go to the FHIR Data Explorer with Hybrid Search and AI Summaries app by @Pietro Di Leo

🏅 4th place and $500 go to the IRIStool and Data Manager app by @Pietro Di Leo

🏅 5th place and $300 go to the yaml-adaptor app by @Yuri Marx   

🌟 $100 go to the gj :: configExplorer app by @John Murray

🌟 $100 go to the quarkus-iris-monitor-system app by @Davi Massaru Teixeira Muta  

🌟 $100 go to the Snapshot of free disk space app by @Robert Cemper

🌟 $100 go to the irisconns app by @Eric Fortenberry

🌟 $100 go to the SentinelIris app by @André Dienes Friedrich

Community Nomination

🥇 1st place and $1,000 go to the FHIR Data Explorer with Hybrid Search and AI Summaries app by @Pietro Di Leo

🥈 2nd place and $600 go to the yaml-adaptor app by @Yuri Marx

🥉 3rd place and $300 go to the quarkus-iris-monitor-system app by @Davi Massaru Teixeira Muta  

🏅 4th place and $200 go to the golang-fiber-iris-realworld-example-app app by @Dmitry Maslennikov

🏅 5th place and $100 go to the gj :: configExplorer app by @John Murray

Our sincerest congratulations to all the winners!

Join the fun next time ;)

3 条新评论
讨论 (3)4
登录或注册以继续
摘要
· 6 hr 前

InterSystems Developers Publications, Week October 06 - 12, 2025, Digest

Articles
#InterSystems IRIS
Presenting IRIS Tool and Data Manager: Integrating InterSystems IRIS with Python, Pandas, and Streamlit
By Pietro Di Leo
Visualize your InterSystems server configurations using Structurizr
By John Murray
Presenting the FHIR Data Explorer: AI-Powered Hybrid Semantic Search & Patient History Generation
By Pietro Di Leo
Bringing It All Together: Go, GORM, and InterSystems IRIS in Action
By Dmitry Maslennikov
Managing External Language Connections with "irisconns"
By Eric Fortenberry
How Windows users can try gj :: configExplorer standalone
By John Murray
Building a FHIR Vector Repository with InterSystems IRIS and Python through the IRIStool module
By Pietro Di Leo
Enhancing FHIR Data Exploration with Local LLMs: Integrating IRIS and Ollama
By Pietro Di Leo
Expand ObjectScript's ability to process YAML
By Yuri Marx
Writing a REST api service for exporting the generated patient data in .csv
By Kate Lau
IRIS install automation using Ansible
By Enzo Medina
Why do I still see old messages after running the purge task?
By Cecilia Yang
Working with Stream Objects in InterSystems IRIS
By Jack Rack
Analyzing IRIS ^PERFMON Runtime Performance Using the Java Native SDK
By Davi Massaru Teixeira Muta
#Open Exchange
Announcements
#InterSystems IRIS
#IRIS contest
#Global Masters
#Developer Community Official
#Other
#Learning Portal
Questions
#InterSystems IRIS
Data Transform - If OBX 5 contains text Abnormal Flag populates
By Jason Lewins
MQTT IRIS Broker
By Touggourt
%FileSet Throws “Directory Does Not Exist” for Network Path — But DirectoryExists() Returns 1
By Gopal Mani
Web interface for maintaining custom lookup classes (SQL) in HealthShare
By Mary George
BusinessService Failed to create MQTT client
By Touggourt
Is there a way to edit and recompile a deployed class?
By Ali Nasser
How can I implement an efficient multi-shard SQL query in an InterSystems IRIS sharded cluster?
By Jack Rack
Can I implement custom stream compression algorithms in IRIS for %Stream.GlobalBinary?
By Jack Rack
How can I leverage bitmap indexes for performance tuning in a hybrid OLAP/OLTP IRIS workload?
By Jack Rack
How can I implement a secure and scalable multi-tenant architecture in IRIS using namespace isolation and role delegation?
By Jack Rack
How can I write a custom SQL storage strategy for ObjectScript classes in IRIS?
By Jack Rack
How can I use $Order() traversal with lock-free concurrency for real-time analytics in IRIS?
By Jack Rack
Can I customize the IRIS SQL query planner to optimize recursive CTE execution?
By Jack Rack
How do I stream process and ETL terabyte-scale HL7/FHIR data using InterSystems IRIS Interoperability?
By Jack Rack
How do I perform predicate pushdown optimization in IRIS embedded SQL with dynamic joins? Body:
By Jack Rack
Can I implement row-level security in InterSystems IRIS using class parameters and runtime filters?
By Jack Rack
How can I write a custom JSON adapter to serialize hierarchical IRIS objects with circular references?
By Jack Rack
How do I implement eventual consistency with custom conflict resolution in IRIS mirroring or async replication?
By Jack Rack
How can I implement an event-sourced architecture with journal-based replay using IRIS globals?
By Jack Rack
How can I design a dynamic class schema generator in ObjectScript based on runtime JSON input?
By Jack Rack
How do I analyze and tune parallel query execution in IRIS SQL engine for complex joins?
By Jack Rack
How can I write an IRIS interoperability adapter for high-throughput WebSocket connections?
By Jack Rack
How can I create a hybrid REST and GraphQL API layer over IRIS data using ObjectScript?
By Jack Rack
How do I trace IRIS internal locking behavior for debugging deadlocks in object transactions?
By Jack Rack
How do I build a custom cost-based query optimizer rule in IRIS SQL engine?
By Jack Rack
How can I integrate InterSystems IRIS with Apache Flink for real-time event stream processing?
By Jack Rack
How do I implement secure identity federation (OAuth2, SAML) for InterSystems IRIS web apps?
By Jack Rack
Can I hook into the IRIS SQL compiler to inject dynamic policies (e.g., tenant filtering, row masking)?
By Jack Rack
How do I trace low-level deadlocks between globals, SQL tables, and object transactions across mirrored IRIS instances?
By Jack Rack
Can I build a decentralized ledger (DLT) inside InterSystems IRIS using deterministic globals and consensus modules?
By Jack Rack
Can I build a custom task scheduler inside IRIS with CRON-like rules, retry policies, and distributed execution?
By Jack Rack
#InterSystems IRIS for Health
Discussions
October 06 - 12, 2025Week at a GlanceInterSystems Developer Community
文章
· 6 hr 前 阅读大约需 8 分钟

Optimizing SQL LIKE Security, Performance and Best Practices

In my previous article, Using LIKE with Variables and Patterns in SQL, we explored how the LIKE predicate behaves in different scenarios, from Embedded SQL to Dynamic SQL, and what happens to performance when wildcards and variables come into play. That piece was about getting comfortable writing a working LIKE query. But writing SQL that works is only the starting point. To build applications that are reliable, scalable, and secure, you need to understand the best practices that underpin all SQL, including queries that use LIKE.

This article takes the next step. We’ll look at a few key points to help strengthen your SQL code, avoid common pitfalls, and make sure your SELECT statements run not just correctly, but also efficiently and safely. I'll use SELECT statements with LIKE predicate as an example along the way, showing how these broader principles directly affect your queries and their results.

*This is what Gemini came up with for this article, kinda cute.

Safety and Security

First and foremost, a high-performance application is meaningless if it is not secure. When using LIKE with user-supplied input, the most significant threat is SQL Injection, which can compromise the integrity of your results and the security of your entire database.

Let me remind you that SQL Injection is currently ranked as A03:2021 – Injection, which places it at #3 on the OWASP Top 10 list for 2021. Although the 2021 OWASP update moved it from the top spot to third, this threat remains relevant and impactful, albeit not the most prevalent issue. Another change was that the scope was broadened from just SQL Injection to Injection in general, encompassing SQL, NoSQL, OS commands, and others. And it was flagged in 94% of tested applications, with an average incidence rate of 3.37%, making it one of the more common vulnerability areas.

So, how can you protect yourself from it? The other day, one of the members posted a question on the Community with a code sample that was vulnerable to precisely this. They passed user input directly as part of the query string, thereby giving an attacker the opportunity to inject malicious SQL code into the query, alter it, and potentially gain unauthorized access or modify data. 

This issue is covered in several articles, recently published mine in French ( I completely forgot that I haven't translated it into English 👼) and @Ash.Sherzhanov's in English. Long story short, avoid concatenating user input directly into the SQL statement. So, DO NOT do this:

 SET input = "Smith"
 SET statement = ##class(%SQL.Statement).%New()
 DO statement.%Prepare("SELECT * FROM Banking.Person WHERE name LIKE '%"_input_"%'")
 SET rs = statement.%Execute()
 DO rs.%Display()

In this case, the attacker can use the input to pass a malicious piece of code, for example:

 SET input = "' or 1=1 --"
 SET statement = ##class(%SQL.Statement).%New()
 DO statement.%Prepare("SELECT * FROM Banking.Person WHERE name LIKE '%"_input_"%'")
 SET rs = statement.%Execute()
 DO rs.%Display()

Essentially, the attacker can gather all the information about the bank's clients without any prior knowledge.

Instead, use the placeholder "?":

 SET input = "Smith"
 SET statement = ##class(%SQL.Statement).%New()
 DO statement.%Prepare("SELECT * FROM Banking.Person WHERE name LIKE ?")
 SET rs = statement.%Execute("%"_input_"%")
 DO rs.%Display()

Best Practices: 

  • Use prepared parameters. They separate the query structure from the input values, thus prohibiting attackers from injecting malicious SQL code. In Dynamic SQL, it's a placeholder "?", in Embedded SQL, it's a named parameter preceded by ":".
  • User input validation. Validating user input before inserting it into SQL queries is another important preventative measure. Use regular expressions or appropriate validation functions to check the validity of the data.
  • Use patterns in class descriptions. This is similar to the previous point, but allows you to verify input when adding new instances.
  • Special Character Filtering. Filtering out special characters that can be used to inject SQL code can also help prevent attacks. Use appropriate filtering functions to remove or escape potentially dangerous characters.
  • Use Stored Procedures. Stored procedures are database objects that encapsulate a set of SQL statements, allowing for efficient execution and reuse. By using stored procedures, you can centralize your application logic and reduce the risk of SQL injections.
  • Regularly Update Software Components. Ensure that you regularly update InterSystems IRIS and its related software components to benefit from the latest security patches.

Performance

A performant application can handle high volumes of data and concurrent users without delay. At the heart of this performance lies the efficiency of your SQL queries. A slow query might time out, or in a concurrent system, it might lock resources and produce inconsistent results. For a query using the LIKE predicate, the difference between a fast and a slow execution plan can completely alter the user experience and the reliability of the data returned.

1. We are all familiar with indexes and their ability to significantly improve query performance. However, apart from having the correct indexes, we also need to utilize them effectively. For a LIKE query, the presence and proper design of an index, as well as its usage, determine whether the database performs a quick search or a time-consuming full-table scan.

If we look at the example above, it's not very index-friendly. When a LIKE pattern begins with a wildcard, a standard B-tree index cannot be used to narrow the search. The database is forced to scan every single row in the table to find a match. For large tables, this results in a slow query that may appear to hang and could even time out, effectively preventing you from obtaining any results at all. Therefore, DO NOT write queries like this:

SELECT * FROM Banking.Person WHERE name LIKE '%Smith%'

This will require a full table or index scan to find "Smith" anywhere in the name, including both first and last names.

Instead, if you know the first letters of the string you're looking for, provide them without a wildcard (% or _) in the beginning:

SELECT * FROM Banking.Person WHERE name LIKE 'Smith%'

Better yet, use the %STARTSWITH predicate instead of LIKE:

 SET input = "Smith"
 SET statement = ##class(%SQL.Statement).%New()
 DO statement.%Prepare("SELECT * FROM Banking.Person WHERE name %STARTSWITH ?")
 SET rs = statement.%Execute(input)
 DO rs.%Display()

In this case, the database can perform a fast index scan, drastically reducing query time. This ensures a quick retrieval of results.

A little interesting tidbit for you, by default, %STARTSWITH and LIKE string comparisons are not case-sensitive. So the following query will return the same result:

 Set input = "smith%"
 SET statement = ##class(%SQL.Statement).%New()
 DO statement.%Prepare("SELECT * FROM Banking.Person WHERE name LIKE ?")
 SET rs = statement.%Execute(input)
 DO rs.%Display()

2. Another way to influence query performance is to use the proper collation for a string property. IRIS offers several collations, with the most common being:

  • SQLUPPER: The default collation for most string data types, it performs case-insensitive comparisons by internally converting both the column value and the pattern to uppercase before comparison. While convenient, this internal operation can introduce a small performance overhead compared to a direct binary comparison.
  • SQLSTRING: This collation performs a case-sensitive, exact binary comparison. It is often faster for equality and LIKE comparisons where case-sensitivity is required, as it avoids the internal conversion step.

If case-sensitivity or specific linguistic sorting is required, explicitly define the collation for the column or use SQLSTRING in the LIKE clause. This prevents the database from performing an unexpected or inefficient case-insensitive comparison.

If, for some reason, you can't / don't want to apply collation to the property itself, you can always use the SQL collation function %SQLSTRING. This converts the expression to a format that is sorted as a case-sensitive string. %SQLSTRING strips trailing whitespace (spaces, tabs, and so on) from the string, then adds one leading blank space to the beginning of the string.

Therefore, if you want to find all "Smith"s and not "smith" or any other kind of "sMith", you can use %SQLSTRING directly in your SQL statement:

 SET input = "Smith%"
 SET statement = ##class(%SQL.Statement).%New()
 DO statement.%Prepare("SELECT * FROM Banking.Person WHERE %SQLSTRING name LIKE %SQLSTRING ?")
 SET rs = statement.%Execute(input)
 DO rs.%Display()

This example uses the %SQLSTRING format to make this comparison case-sensitive. It returns all names that begin with “Smith”. Note that in this case, you should apply %SQLSTRING collation to both sides of the statement. However, if the column itself already has SQLSTRING collation defined in the class property, you only need to apply %SQLSTRING to the literal or variable being compared, as the column is already in the desired collation. If the column has SQLUPPER (the default), then applying %SQLSTRING to both sides correctly overrides the column's default.

Best Practices: 

  • Be mindful of wildcards. If at all possible, try to avoid using them as the first symbol in the search string.
  • Get the best use of collation. Consider your most common queries and set up collation either directly in the class description or in the query itself.

To sum up, the LIKE predicate is a versatile and powerful tool for pattern matching. However, its effectiveness and reliability are intrinsically linked to broader principles of performance and security. A LIKE query with a leading wildcard might fail to return results in a timely manner, while a vulnerable LIKE query can be manipulated to return an entirely different set of results than intended. By combining the syntax and variable-handling techniques from the previous article with the best practices of indexing and a steadfast commitment to parameterized queries, you can ensure that your LIKE statements are not only functional but also fast, secure, and reliable, consistently providing your application with the correct results.

讨论 (0)1
登录或注册以继续
问题
· 6 hr 前

Sorting by number field type in FDN

I have a custom defined priority field that is being stored as a number type

<record name="LocalClinicalMeSHTerms" type="serial">
<field name="LocalClinicalExpertiseCodedValue" type="{CODETYPE}" codeFamily="HSPD" codeTable="LocalClinicalExpertise" codeScheme="{MASTER}"/>
<field name="LocalCliniclDisplayOrder" type="number"/>
</record>

However, within the overviewIndividual.cls form

				{
					"type": "HSPD.collection",
					"key": "LocalClinicalMeSHTerms",
					"hideExpression": "formState.lib.hideField(formState) && model.LocalClinicalMeSHTerms==''",
					"templateOptions": {
						"label": "LocalClinicalMeSHTerms"
					},
					"data": {
						"collections": {
							"editAs": "inline",
							"pager": {
								"suppressPaging": true
							}
						},
						"pd": {
							"corrections": {
								"display": "formState.lib.getCorrectionsDisplayForArray(model[options.key], 'row.CodedValue.Description', this)"
							}
						},
						"embeddedLabel": "MeSHTerm",
						"embeddedFields": [
							{
								"type": "HSPD.select",
								"key": "LocalClinicalExpertiseCodedValue",
								"templateOptions": {
									"label": "Type",
									"options": [
										{
											"Description": "",
											"_class": "HS.DataManager.Datatype.CodeItem"
										}
									]
								},
								"data": {
									"codeTable": "HSPD.LocalClinicalExpertise",
									"orderField": "Description"
								}
							},
							{
								"type": "input",
								"key": "LocalCliniclDisplayOrder",
								"templateOptions": {
									"type": "number",
									"label": "Priority",
									"model":[
										{
											"minSize":1
										}
									]								}
							}
						]
					}
				}

 

when I first return results from by search it is sorting by highest value so if an Individual had 11 fields, it would display starting with 11.

If I click the sorting function at the top of the column it is not sorting by numeric value.

Anyone have an idea on how I can return the results in the correct "Priority" order and then properly sort the order correctly?

讨论 (0)1
登录或注册以继续
  •  
  • 当前 1,最大 1000
  • ››